按组使用 cov.wt 和 data.table 的加权相关性

Weighted correlation using cov.wt and data.table by group

我有一个像这样的data.table

set.seed(12345)
mydt <- data.table(gr1 = sample(letters[1:2], size = 100, replace = TRUE),
        gr2 = sample(letters[3:4], size = 100, replace = TRUE),
        a = rnorm(100), b = rnorm(100), weight = rnorm(100, 5, 1))

gr1gr2 指定每个案例的组成员资格。我想通过 gr1gr2 指定的组成员资格,使用 weight 列从 cov.wt 函数获取相关矩阵。 cov.wt returns 相关矩阵if cor = TRUE。我可以将 mydt 拆分为 gr1gr2,然后使用 lapply 进行计算并提取每个相关矩阵:

mydt <- split(x = mydt, by = c("gr1", "gr2"), drop = TRUE)

lapply(X = mydt, FUN = function(i) {
  cov.wt(x = as.matrix(i[ , c("a", "b")]), wt = i[ , weight], cor = TRUE)[["cor"]]
})

我得到了我想要的:

$b.c
                    a                   b
a 0.99999999999999978 0.26861150206539375
b 0.26861150206539375 0.99999999999999978

$a.c
                     a                    b
a  0.99999999999999978 -0.13281683546112405
b -0.13281683546112405  1.00000000000000000

$b.d
                     a                    b
a  1.00000000000000000 -0.13064774898011455
b -0.13064774898011455  1.00000000000000000

$a.d
                     a                    b
a  0.99999999999999978 -0.61122086293705469
b -0.61122086293705458  0.99999999999999978

但是,对于大型数据集,这种方法相当慢。我想用 data.table 的方式来实现这个,就像 Dan Y 的 post 一样。你,我很挣扎,因为额外的参数和从 cov.wt 函数返回的列表中提取相关矩阵。我尝试了以下(加上许多变体):

mydt[ , .(cov.wt(as.matrix(a, b), wt = weight, cor = TRUE)["cor"]), by = c("gr1", "gr2")]

最后得到的只是每个矩阵对角线的第一个值

我做错了什么?

这里的as.matrix是错误的,因为'x'是单个元素而不是多个(基于?as.matrix)。一种选择是通过 cbind 将向量 'a'、'b' 转换为矩阵,然后将输出包装在列表中(使用 .()

library(data.table)
out <- mydt[ , .(.(cov.wt(cbind(a,b), wt = weight, cor = TRUE)["cor"])), 
    by = c("gr1", "gr2")]
out$V1
#[[1]]
#[[1]]$cor
#          a         b
#a 1.0000000 0.2686115
#b 0.2686115 1.0000000


#[[2]]
#[[2]]$cor
#           a          b
#a  1.0000000 -0.1328168
#b -0.1328168  1.0000000


#[[3]]
#[[3]]$cor
#           a          b
#a  1.0000000 -0.1306477
#b -0.1306477  1.0000000


#[[4]]
#[[4]]$cor
#           a          b
#a  1.0000000 -0.6112209
#b -0.6112209  1.0000000

注意:由于种子不同,值存在差异