2010-08-26 6 views
40

У меня есть dataframe и вы хотите рассчитать correlation (со Spearman, данные категоричны и ранжированы), но только для подмножества столбцов. Я пробовал все, но функция R() принимает только числовые данные (x должно быть числовым, говорит сообщение об ошибке), даже если используется Spearman.Вычислить корреляцию - cor() - только для подмножества столбцов

Один грубый подход заключается в удалении нечисловых столбцов из блока данных. Это не так изящно, для скорости я до сих пор не хочу рассчитать корреляции между все столбцов.

Надеюсь, есть способ просто сказать «рассчитать корреляции для столбцов x, y, z». Ссылки столбцов могут быть указаны по номеру или по имени. Я предполагаю, что гибкий способ обеспечить их будет через вектор.

Любые предложения приветствуются.

ответ

55

, если у вас есть dataframe, где некоторые столбцы являются числовыми и некоторые из них другие (символ или фактор) и вы хотите сделать корреляции для числовых столбцов, вы можете сделать следующее:

set.seed(10) 

x = as.data.frame(matrix(rnorm(100), ncol = 10)) 
x$L1 = letters[1:10] 
x$L2 = letters[11:20] 

cor(x) 

Error in cor(x) : 'x' must be numeric 

но

cor(x[sapply(x, is.numeric)]) 

      V1   V2   V3   V4   V5   V6   V7 
V1 1.00000000 0.3025766 -0.22473884 -0.72468776 0.18890578 0.14466161 0.05325308 
V2 0.30257657 1.0000000 -0.27871430 -0.29075170 0.16095258 0.10538468 -0.15008158 
V3 -0.22473884 -0.2787143 1.00000000 -0.22644156 0.07276013 -0.35725182 -0.05859479 
V4 -0.72468776 -0.2907517 -0.22644156 1.00000000 -0.19305921 0.16948333 -0.01025698 
V5 0.18890578 0.1609526 0.07276013 -0.19305921 1.00000000 0.07339531 -0.31837954 
V6 0.14466161 0.1053847 -0.35725182 0.16948333 0.07339531 1.00000000 0.02514081 
V7 0.05325308 -0.1500816 -0.05859479 -0.01025698 -0.31837954 0.02514081 1.00000000 
V8 0.44705527 0.1698571 0.39970105 -0.42461411 0.63951574 0.23065830 -0.28967977 
V9 0.21006372 -0.4418132 -0.18623823 -0.25272860 0.15921890 0.36182579 -0.18437981 
V10 0.02326108 0.4618036 -0.25205899 -0.05117037 0.02408278 0.47630138 -0.38592733 
       V8   V9   V10 
V1 0.447055266 0.210063724 0.02326108 
V2 0.169857120 -0.441813231 0.46180357 
V3 0.399701054 -0.186238233 -0.25205899 
V4 -0.424614107 -0.252728595 -0.05117037 
V5 0.639515737 0.159218895 0.02408278 
V6 0.230658298 0.361825786 0.47630138 
V7 -0.289679766 -0.184379813 -0.38592733 
V8 1.000000000 0.001023392 0.11436143 
V9 0.001023392 1.000000000 0.15301699 
V10 0.114361431 0.153016985 1.00000000 
+6

, если вы действительно хотите только, чтобы сделать корреляцию на столбцах 1, 3 и 10, вы всегда можете сделать 'Сог (х [С (1, 3, 10)])' – Greg

+1

Извините, это числовые, а не нечисловые данные. Я оставлю это на всякий случай. – Greg

+1

рад, что вы его оставили, Грег. Вы уже помогли кому-то - это уже помогло мне использовать sapply в другом творческом ключе :) –

13

Для цифровых данных у вас есть решение. Вы сказали, что это категорические данные. Затем жизнь становится немного сложнее ...

Ну, во-первых: сумма связи между двумя категориальными переменными не измеряется с помощью ранговой корреляции Спирмена, но, например, с критерием Хи-квадрат. На самом деле это логика. Ранжирование означает, что в ваших данных есть определенный порядок. Теперь скажите мне, что больше, желтое или красное? Я знаю, иногда R выполняет корреляцию рангов копья на категориальных данных. Если я закодирую желтый 1 и красный 2, R будет считать красным больше желтого.

Итак, забудьте о Spearman для категориальных данных. Я продемонстрирую chisq-тест и как выбрать столбцы с помощью combn(). Но вы бы извлечь выгоду из немного больше времени с книгой Агрести в: http://www.amazon.com/Categorical-Analysis-Wiley-Probability-Statistics/dp/0471360937

set.seed(1234) 
X <- rep(c("A","B"),20) 
Y <- sample(c("C","D"),40,replace=T) 

table(X,Y) 
chisq.test(table(X,Y),correct=F) 
# I don't use Yates continuity correction 

#Let's make a matrix with tons of columns 

Data <- as.data.frame(
      matrix(
      sample(letters[1:3],2000,replace=T), 
      ncol=25 
     ) 
     ) 

# You want to select which columns to use 
columns <- c(3,7,11,24) 
vars <- names(Data)[columns] 

# say you need to know which ones are associated with each other. 
out <- apply(combn(columns,2),2,function(x){ 
      chisq.test(table(Data[,x[1]],Data[,x[2]]),correct=F)$p.value 
     }) 

out <- cbind(as.data.frame(t(combn(vars,2))),out) 

Тогда вы должны получить:

> out 
    V1 V2  out 
1 V3 V7 0.8116733 
2 V3 V11 0.1096903 
3 V3 V24 0.1653670 
4 V7 V11 0.3629871 
5 V7 V24 0.4947797 
6 V11 V24 0.7259321 

Где V1 и V2 показывают, между которыми переменными он идет, и «из» дает значение p для ассоциации. Здесь все переменные независимы. Что бы вы ожидали, поскольку я создал данные наугад.

+0

Извините, у меня есть тенденция часто встраивать функции, чтобы избежать слишком много переменных в моей рабочей области. Если вы не можете понять код, просто спросите, и я объясню, что он делает. –

+0

спасибо. Я фактически забыл упомянуть в вопросе о том, что данные категоричны, но оцениваются (уровень одобрения с чем-то). Тем не менее, вы получаете голосование за код (из которого я все равно узнаю материал) и для справки по книге. – wishihadabettername

+0

ах, ОК. Это объясняет :-) Извините за лекцию, тогда никакого вреда не было. Я все равно могу порекомендовать Агрешть. Это стандарт, когда дело доходит до анализа категориальных данных. –

1

Я нашел более простой способ взглянуть на скрипт R, созданный Rattle. Это выглядит, как показано ниже:

correlations <- cor(mydata[,c(1,3,5:87,89:90,94:98)], use="pairwise", method="spearman") 
+0

Это почти то, что [Грег написал в комментарии для своего ответа] (http://stackoverflow.com/questions/3571909/r-how-to-calculate-correlation-cor-for-only-a-subset-of -columns/3572115 # 3572115). – Marek

+1

Ах, ладно, меня отвлекало использование sapply(). – wishihadabettername