Вычислить корреляцию - cor () - только для подмножества столбцов - PullRequest
44 голосов
/ 26 августа 2010

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

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

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

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

Ответы [ 4 ]

61 голосов
/ 26 августа 2010

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

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
15 голосов
/ 26 августа 2010

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

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

Итак, забудьте о Спирмане для категориальных данных.Я продемонстрирую 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 указывают, между какими переменными он идет,и "out" дает значение p для ассоциации.Здесь все переменные независимы.Что и следовало ожидать, поскольку я создал данные наугад.

2 голосов
/ 27 августа 2010

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

correlations <- cor(mydata[,c(1,3,5:87,89:90,94:98)], use="pairwise", method="spearman")
0 голосов
/ 05 июня 2019

Другим вариантом будет просто использовать превосходный пакет corrr https://github.com/drsimonj/corrr и делать

require(corrr)
require(dplyr)

myData %>% 
   select(x,y,z) %>%  # or do negative or range selections here
   correlate() %>%
   rearrange() %>%  # rearrange by correlations
   shave() # Shave off the upper triangle for a cleaner result

Шаги 3 и 4 являются полностью необязательными и включены только для демонстрации полезностипакет.

...