【问题标题】:Weighted correlation using cov.wt and data.table by group按组使用 cov.wt 和 data.table 的加权相关性
【发布时间】:2020-08-05 21:35:42
【问题描述】:

我有一个像这样的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 指定每个案例的组成员身份。我想使用weight 列通过gr1gr2 指定的组成员资格从cov.wt 函数中获取相关矩阵。如果cor = TRUEcov.wt 返回相关矩阵。我可以将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 under this question 的帖子一样。你,我很挣扎,因为额外的参数和从cov.wt 函数返回的列表中提取相关矩阵。我尝试了以下(加上许多变体):

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

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

我做错了什么?

【问题讨论】:

    标签: r data.table grouping weighted


    【解决方案1】:

    这里,as.matrix 是错误的,因为“x”是单个元素而不是多个元素(基于 ?as.matrix)。一种选择是通过cbinding 向量'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
    

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

    【讨论】:

    • 天啊,你真快!非常感谢,这解决了问题。也谢谢你的解释。
    • 抱歉,我还有一个问题。我可以将 wt 作为字符串传递(即 get("weight"),但如何将 a 和 b 作为字符串传递(即 my.cols &lt;- c("a", "b"))cbind,类似于 cbind(my.cols)。我尝试了不同的东西,但它给了我错误“'x' 必须仅包含有限值”。
    • 我明白了:my.cols
    • 谢谢!比我找到的解决方案运行得更快,而且更简单。
    猜你喜欢
    • 2013-07-18
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    相关资源
    最近更新 更多