【问题标题】:Vectorize weighted arithmetics across a matrix向量化矩阵中的加权算术
【发布时间】:2019-06-27 20:09:07
【问题描述】:

我想知道是否有任何方法可以跨矩阵矢量化加权算术。例如用于计算下面给定weightsvalues 的加权平均值:

set.seed(12321)
values = matrix(sample(10:40, 6, replace = TRUE), ncol = 2)
weights = matrix(sample(1:5, 6, replace = TRUE), ncol = 2)

我们可以做到:

w.mean = numeric()

for (i in 1:dim(values)[1]){
  w.mean[i] = stats::weighted.mean(x=values[i,], w =  weights[i,])
}

但是对于大型矩阵来说速度并不快。我想知道是否有使用apply family 或aggregate 或类似的完全矢量化方式。

【问题讨论】:

  • 要将您的代码从for 转换为sapply,您可以使用sapply(1:nrow(values), function(i) weighted.mean(values[i, ], weights[i, ])),但我不确定这是否比for 循环更有效。
  • for 循环可能会尽可能快。你可以试试matrixstats::weightedMean 会更快。什么构成“大”矩阵(即多列、多行,两者都有)?
  • 也许是apply(abind::abind(values, weights, along = 3), 1, function(x) weighted.mean(x[,1], x[,2]))

标签: r weighted


【解决方案1】:

您可以尝试将您的值和权重分组到一个 data.frame 中

value_weight <- data.frame(group = rep(1:2, each = 3), 
                           value = sample(10:40, 6, replace = TRUE), 
                           weight = sample(1:5, 6, replace = TRUE))

然后使用plyr

ddply(value_weight, .(group), # split the data frame according to group
      function(x) data.frame(wret = weighted.mean(x$value, x$weight)))

更多信息here

【讨论】:

    【解决方案2】:

    谢谢大家。真正有见地的答案。我对它们进行了测试,结果证明sapply 很快,然后是abind。但是,在我的原始数据集中,我使用dcast 对分组进行了汇总。然而,在我看到ddply 的建议后,我又回到了它。我意识到使用data.table::data.table 使其速度提高了几个数量级:

    n = 1000
    DT = data.table(id = sample(LETTERS[1:10], size = n, replace = TRUE),
                    value = sample(seq(20,30), size = n, replace = TRUE),
                    weight = sample(seq(1,5), size = n, replace = TRUE))
    
    wtd_var = DT[,lapply(.SD,function(x)(weightedVar(as.numeric(x),w=weight))),by=id,.SDcols='value']
    wtd_var
    
    

    data.table 摇滚,确实!

    【讨论】:

      猜你喜欢
      • 2015-02-23
      • 2019-04-25
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 1970-01-01
      • 2015-04-27
      • 1970-01-01
      • 2014-01-13
      相关资源
      最近更新 更多