数据表中按组加权求和变量

7
我正在寻找一种使用data.table计算变量加权总和的解决方案。我希望这个例子足够清晰易懂。
require(data.table)

dt <- data.table(matrix(1:200, nrow = 10))
dt[, gr := c(rep(1,5), rep(2,5))]
dt[, w := 2]

# Error: object 'w' not found
dt[, lapply(.SD, function(x) sum(x * w)),
   .SDcols = paste0("V", 1:4)]

# Error: object 'w' not found
dt[, lapply(.SD * w, sum),
   .SDcols = paste0("V", 1:4)]

# This works with out groups
dt[, lapply(.SD, function(x) sum(x * dt$w)),
   .SDcols = paste0("V", 1:4)]

# It does not work by groups
dt[, lapply(.SD, function(x) sum(x * dt$w)),
   .SDcols = paste0("V", 1:4), keyby = gr]

# The result to be expected
dt[, list(V1 = sum(V1 * w),
          V2 = sum(V2 * w),
          V3 = sum(V3 * w),
          V4 = sum(V4 * w)), keyby = gr]

### from Aruns answer
dt[, lapply(.SD[, paste0("V", 1:4), with = F],
            function(x) sum(x*w)), by=gr]
1个回答

6

最终尝试(复制Roland的答案 :))

复制 @Roland 的优秀回答:

print(dt[, lapply(.SD, function(x, w) sum(x*w), w=w), by=gr][, w := NULL])

仍不是最有效的方法:(第二次尝试)

根据@Roland的评论,对所有列执行操作,然后只删除不需要的列会更快(前提是操作本身不耗时,这里是这种情况)。

dt[, {lapply(.SD, function(x) sum(x*w))}, by=gr][, w := NULL][]

由于某些原因,在不使用 {} 的情况下似乎找不到 w。不知道为什么。


旧的(低效)答案:

如果有太多的组,子集操作可能很昂贵。

您可以按以下方式在不使用 .SDcols 并将其移除的情况下使用 lapply 进行操作:

dt[, lapply(.SD[, -1, with=FALSE], function(x) sum(x*w)), by=gr]
#    gr V1  V2  V3  V4
# 1:  1 20 120 220 320
# 2:  2 70 170 270 370

.SDcols使.SD不包含w列。因此,在.SD环境范围内,无法使用w进行乘法运算。


2
我怀疑这样做可能会更快(由于data.table的优化),只需在所有列上应用lapply,然后简单地删除w*w列即可。 - Roland
1
Roland,看起来是这样。出于某种原因,除非我使用 {},否则找不到 w。我会进行编辑。也许你知道为什么... - Arun
1
print(dt[, lapply(.SD, function(x, w) sum(x*w), w=w), by=gr][, w := NULL]) - Roland
1
@djhurio,你仍然可以通过以下方式使用它:dt[, lapply(.SD, function(x, w) sum(x*w), w=w), by=gr, .SDcols=c("w", "V1", "V2", "V3", "V4")][, w := NULL] - Arun
1
@Arun,谢谢!在我的情况下,数据集并不是很大。因此,我没有看到无效解决方案带来的明显时间延迟。我会使用它,因为语法更短,更易读。 - djhurio
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接