按组使用 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))
gr1
和 gr2
指定每个案例的组成员资格。我想通过 gr1
和 gr2
指定的组成员资格,使用 weight
列从 cov.wt
函数获取相关矩阵。 cov.wt
returns 相关矩阵if cor = TRUE
。我可以将 mydt
拆分为 gr1
和 gr2
,然后使用 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
注意:由于种子不同,值存在差异
我有一个像这样的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))
gr1
和 gr2
指定每个案例的组成员资格。我想通过 gr1
和 gr2
指定的组成员资格,使用 weight
列从 cov.wt
函数获取相关矩阵。 cov.wt
returns 相关矩阵if cor = TRUE
。我可以将 mydt
拆分为 gr1
和 gr2
,然后使用 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 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
注意:由于种子不同,值存在差异