web-dev-qa-db-ja.com

相関の計算-cor()-列のサブセットのみ

データフレームがあり、 相関 (スピアマンでは、データはカテゴリカルでランク付けされます)を計算したいのですが、列のサブセットのみです。すべて試してみましたが、Rの cor ()関数は、スピアマンが使用されている場合でも、数値データのみを受け入れます(xは数値でなければなりません、エラーメッセージが表示されます)。

総当たり的なアプローチの1つは、非数値列をデータフレームから削除することです。これはそれほどエレガントではありません。速度のために、all列間の相関を計算したくありません。

「列x、y、zの相関を計算する」という簡単な方法があることを願っています。列参照は、番号または名前で参照できます。それらを提供する柔軟な方法は、ベクトルを介することだと思います。

どんな提案も大歓迎です。

45

一部の列が数値で、一部が他の列(文字または因子)であるデータフレームがあり、数値列の相関のみを実行する場合、次の操作を実行できます。

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
62
Greg

数値データには解決策があります。しかし、それはカテゴリデータです。人生はもう少し複雑になります...

まず、2つのカテゴリ変数間の関連の量は、スピアマンランク相関ではなく、たとえばカイ2乗検定で測定されます。これは実際にはロジックです。ランキングとは、データに何らかの順序があることを意味します。黄色と赤のどちらが大きいか教えてください。私は、Rがカテゴリカルデータに対してスピアマンランク相関を実行することがあることを知っています。黄色1と赤2をコーディングすると、Rは赤が黄色よりも大きいと見なします。

したがって、カテゴリーデータのスピアマンについては忘れてください。 chisqテストと、combin()を使用して列を選択する方法を示します。しかし、Agrestiの本でもう少し時間があればメリットがあります: 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値を示します。ここで、すべての変数は独立しています。ランダムにデータを作成したので、あなたはそれを期待するでしょう。

15
Joris Meys

Rattleによって生成されたRスクリプトを見て、簡単な方法を見つけました。以下のようになります。

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

別のオプションは、優れたcorrrパッケージを使用することです https://github.com/drsimonj/corrr そしてdo

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は完全にオプションであり、パッケージの有用性を示すために含まれています。

0
Holger Brandl