【问题标题】:Weighted sum of variables by groups with data.table使用 data.table 分组的变量加权总和
【发布时间】:2013-07-18 14:25:07
【问题描述】:

我正在寻找一种解决方案,用 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]

【问题讨论】:

    标签: r aggregate data.table weighted


    【解决方案1】:

    最后的尝试(复制罗兰的答案:))

    复制@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 列。因此,无法与w 相乘,因为它不存在于.SD 环境范围内。

    【讨论】:

    • 我怀疑它可能会更快(由于 data.table 优化)只覆盖所有列,然后简单地删除 w*w 列。
    • 罗兰,好像是这样。由于某种原因,除非我使用{},否则找不到w。我会进行编辑。也许你会遵循为什么......
    • print(dt[, lapply(.SD, function(x, w) sum(x*w), w=w), by=gr][, w := NULL])
    • @djhurio,不,您仍然可以通过以下方式使用它:dt[, lapply(.SD, function(x, w) sum(x*w), w=w), by=gr, .SDcols=c("w", "V1", "V2", "V3", "V4")][, w := NULL]
    • @Arun,谢谢!在我的案例中,数据集并没有那么大。因此,我认为无效的解决方案不会出现明显的时间滞后。我将使用它,因为语法更短且更易读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2015-09-05
    • 1970-01-01
    • 2020-08-05
    • 1970-01-01
    相关资源
    最近更新 更多