R data.table中各组之间的相关性

Bra*_*ser 10 r correlation data.table

如果这些值按组存储在data.table的单个列中(除了将data.table转换为矩阵之外),是否有一种优雅计算值之间相关性的方法?

library(data.table)
set.seed(1)             # reproducibility
dt <- data.table(id=1:4, group=rep(letters[1:2], c(4,4)), value=rnorm(8))
setkey(dt, group)

#    id group      value
# 1:  1     a -0.6264538
# 2:  2     a  0.1836433
# 3:  3     a -0.8356286
# 4:  4     a  1.5952808
# 5:  1     b  0.3295078
# 6:  2     b -0.8204684
# 7:  3     b  0.4874291
# 8:  4     b  0.7383247
Run Code Online (Sandbox Code Playgroud)

有效的东西,但需要组名作为输入:

cor(dt["a"]$value, dt["b"]$value)
# [1] 0.1556371
Run Code Online (Sandbox Code Playgroud)

我正在寻找更多类似的东西:

dt[, cor(value, value), by="group"]
Run Code Online (Sandbox Code Playgroud)

但这并没有给我我追求的相关性.

对于具有正确结果的矩阵,这是同样的问题.

set.seed(1)             # reproducibility
m <- matrix(rnorm(8), ncol=2)
dimnames(m) <- list(id=1:4, group=letters[1:2])

#        group
# id           a          b
#   1 -0.6264538  0.3295078
#   2  0.1836433 -0.8204684
#   3 -0.8356286  0.4874291
#   4  1.5952808  0.7383247

cor(m)                  # correlations between groups

#           a         b
# a 1.0000000 0.1556371
# b 0.1556371 1.0000000
Run Code Online (Sandbox Code Playgroud)

任何评论或帮助非常感谢.

Sco*_*hie 6

没有简单的方法可以做到这一点data.table.您提供的第一种方式:

cor(dt["a"]$value, dt["b"]$value)
Run Code Online (Sandbox Code Playgroud)

可能是最简单的.

另一种方法是reshapedata.table"long"格式到"wide"格式:

> dtw <- reshape(dt, timevar="group", idvar="id", direction="wide")
> dtw
   id    value.a    value.b
1:  1 -0.6264538  0.3295078
2:  2  0.1836433 -0.8204684
3:  3 -0.8356286  0.4874291
4:  4  1.5952808  0.7383247
> cor(dtw[,list(value.a, value.b)])
          value.a   value.b
value.a 1.0000000 0.1556371
value.b 0.1556371 1.0000000
Run Code Online (Sandbox Code Playgroud)

更新:如果您使用的是data.table版本> = 1.9.0,那么您可以使用dcast.data.table更快的速度.查看此帖子了解更多信息.

dcast.data.table(dt, id ~ group)
Run Code Online (Sandbox Code Playgroud)

  • 你知道'dcast.data.table`吗? (2认同)
  • @ScottRitchie,不是真的.我认为你混淆了Hadley软件包的基本功能.`reshape`是一个基函数,它可以在`data.table`的*all*版本上正常工作.`reshape`和`reshape2`也是包含函数melt/cast的包.`data.table> = 1.9.0`版本实现`melt`和`dcast`方法并导入`reshape2`. (2认同)

Cor*_*one 6

我不知道如何立即以矩阵形式获取它,但我觉得这个解决方案很有用:

dt[, {x = value; dt[, cor(x, value), by = group]}, by=group]

   group group        V1
1:     a     a 1.0000000
2:     a     b 0.1556371
3:     b     a 0.1556371
4:     b     b 1.0000000
Run Code Online (Sandbox Code Playgroud)

因为你从一个熔化的数据集开始,你最终得到了相关性的熔融表示.

使用此表单,您还可以选择仅计算某些对,尤其是计算两个对角线时间的浪费.例如:

 dt[, {x = value; g = group; dt[group <= g, list(cor(x, value)), by = group]}, by=group]
   group group        V1
1:     a     a 1.0000000
2:     b     a 0.1556371
3:     b     b 1.0000000
Run Code Online (Sandbox Code Playgroud)

或者,此形式也适用于两组之间的互相关(即对角线的块)

library(data.table)
set.seed(1)             # reproducibility
dt1 <- data.table(id=1:4, group=rep(letters[1:2], c(4,4)), value=rnorm(8))
dt2 <- data.table(id=1:4, group=rep(letters[3:4], c(4,4)), value=rnorm(8))
setkey(dt1, group)
setkey(dt2, group)

dt1[, {x = value; g = group; dt2[, list(cor(x, value)), by = group]}, by=group]

   group group          V1
1:     a     c -0.39499814
2:     a     d  0.74234458
3:     b     c  0.96088312
4:     b     d  0.08016723
Run Code Online (Sandbox Code Playgroud)

显然,如果你最终想要矩阵形式的那些,那么你可以使用dcast或者dcast.data.table注意到在上面的例子中你有两个具有相同名称的列,为了解决这个问题,值得在j函数中重命名它们.对于原始问题:

dcast.data.table(dt[, {x = value; g1=group; dt[, list(g1, g2=group, c =cor(x, value)), by = group]}, by=group], g1~g2, value.var = "c")

   g1         a         b
1:  a 1.0000000 0.1556371
2:  b 0.1556371 1.0000000
Run Code Online (Sandbox Code Playgroud)


Cor*_*one 5

从那以后,我找到了一个甚至更简单的替代方法。您实际上与您的dt[, cor(value, value), by="group"]方法非常接近。您真正需要的是首先对日期进行笛卡尔联接,然后再分组。即

dt[dt, allow.cartesian=T][, cor(value, value), by=list(group, group.1)]
Run Code Online (Sandbox Code Playgroud)

这样的好处是它将系列连在一起(而不是假设它们的长度相同)。然后,您可以将其转换为矩阵形式,或将其保留为在ggplot等图中作为热图进行绘制。

完整的例子

setkey(dt, id)
c <- dt[dt, allow.cartesian=T][, list(Cor = cor(value, value.1)), by = list(group, group.1)]
c

   group group.1       Cor
1:     a       a 1.0000000
2:     b       a 0.1556371
3:     a       b 0.1556371
4:     b       b 1.0000000

dcast(c, group~group.1, value.var = "Cor")

  group         a         b
1     a 1.0000000 0.1556371
2     b 0.1556371 1.0000000
Run Code Online (Sandbox Code Playgroud)