【问题标题】:Calculate correlation with cor(), only for numerical columns使用 cor() 计算相关性,仅适用于数值列
【发布时间】:2011-04-04 01:39:04
【问题描述】:

我有一个数据框,想计算 correlation(使用 Spearman,数据是分类的和排名的),但仅适用于列的子集。我尝试了所有,但 R 的 cor() 函数只接受数字数据(x 必须是数字,错误消息说),即使使用了 Spearman。

一种粗暴的方法是从数据框中删除非数字列。这不是那么优雅,为了速度,我仍然不想计算 all 列之间的相关性。

我希望有一种方法可以简单地说“计算列 x、y、z 的相关性”。列引用可以按编号或名称。我想提供它们的灵活方式是通过向量。

感谢任何建议。

【问题讨论】:

标签: r correlation


【解决方案1】:

如果您有一个数据框,其中一些列是数字列,而另一些列是其他列(字符或因子),并且您只想对数字列进行关联,您可以执行以下操作:

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

【讨论】:

  • 如果您真的只想对第 1、3 和 10 列进行关联,您可以随时使用 cor(x[c(1, 3, 10)])
  • 对不起,这是针对数字的,不是非数字的数据。我会留下它以防万一。
  • 很高兴你离开了,格雷格。你已经帮助了某个人——它已经帮助我以另一种创造性的方式实现了 sapply :)
【解决方案2】:

对于数值数据,您有解决方案。但它是分类数据,你说。然后生活变得有点复杂......

首先:两个分类变量之间的关联量不是用 Spearman 等级相关性来衡量的,而是用卡方检验来衡量的。这实际上是逻辑。排名意味着您的数据中有一定的顺序。现在告诉我哪个更大,黄色还是红色?我知道,有时 R 确实对分类数据执行 spearman 等级相关。如果我编码黄色 1 和红色 2,R 会认为红色大于黄色。

所以,别管斯皮尔曼的分类数据了。我将演示 chisq-test 以及如何使用 combn() 选择列。但是您会从 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 值。这里所有的变量都是独立的。这是您所期望的,因为我是随机创建数据的。

【讨论】:

  • 抱歉,我倾向于经常嵌套函数以避免工作区中有太多空闲变量。如果您无法理解代码,请询问,我会解释它的作用。
  • 谢谢。我实际上忘了在问题中提到数据是分类的但排名(对某事的认可程度)。尽管如此,你还是会为代码(无论如何我会从中学到东西)和书籍参考投票。
  • 啊,好的。这解释了:-) 对不起,那次讲座,没有伤害的意思。无论如何,我绝对可以推荐 Agresti。它是分类数据分析的标准。
  • 很好的答案,我找不到更好的例子来完成这项任务。一个问题,什么值的 p 值表示因变量?
  • @Eduardo 当表格的两个维度之间存在依赖关系时,卡方检验会给出显着的结果。将其视为一个简单的“回归”:这也是 X 和 Y 之间的依赖关系。也就是说,哪个 p 值取决于数据以及您如何处理多个测试。但为此,我实际上参考了一本好书。
【解决方案3】:

通过查看 Rattle 生成的 R 脚本,我找到了一种更简单的方法。如下所示:

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

【讨论】:

  • 这几乎就是Greg wrote in a comment for his answer的内容。
  • 啊,好吧,我被 sapply() 的使用弄得一头雾水。
  • 最好有一个通用方法来查找所有数字列,而不是硬编码列索引(如果添加/删除分类列怎么办?或插入/删除非分类列?任何其中会破坏这段代码)
【解决方案4】:

另一种选择是只使用出色的corrrhttps://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 步完全是可选的,只是为了展示包的实用性而包含在内。

【讨论】:

    猜你喜欢
    • 2018-07-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2011-04-17
    • 2013-01-29
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多