【问题标题】:modifying data.table by reference with 'lapply' and 'by' creates duplicate rows for grouping columns使用 'lapply' 和 'by' 通过引用修改 data.table 会为分组列创建重复行
【发布时间】:2018-11-06 02:50:56
【问题描述】:

这可能以前被问过,我已经查看了Reference semantics,但我似乎找不到答案。 SO还建议修改我的标题,所以如果有人发布答案的链接我会很好!

我在下面有一个 MWE。我正在尝试按每个月的某天按val 列分组。据我了解,在代码下面的场景 1 中,由于我没有通过 := 将 lapply 的值分配给任何新列,因此会打印 data.table。

但是,在场景 2 中,当我使用 := 通过引用分配新列变量时,会创建新列(使用正确的值),但是当我只需要每天时,该值会在一天中的每个小时重复价值观。

场景 3 也给出了预期的结果,但需要创建一个新的 data.table。

我也不会想到set,因为value 按行迭代,我需要对某些列进行分组。

感谢您的帮助,

library(data.table)
library(magrittr)

set.seed(123)

# create data.table to group by
dt <- data.table(year = rep(2018, times = 24 * 31),
                 month = rep(1, times = 24 * 31),
                 day = rep(1:31, each = 24),
                 hour = rep(0:23, times = 31)) %>% 
  .[, val := sample(100, size = nrow(dt), replace = TRUE)]


# SCENARIO 1
# creates desired dataframe but only prints it, doesn't modify dt by reference (because it is missing `:=`)
dt[, lapply(.SD,
            sum),
   .SDcols = "val",
   by = .(year,
          month,
          day)]


# Scenario 2
# creates desired val column, but creates duplicate val values for all rows of original grouping by data.table
dt[, val := lapply(.SD,
                   sum),
   .SDcols = "val",
   by = .(year,
          month,
          day)]


# SCENARIO 3
# this also works, but requires creating a new data.table
new_dt <- dt[, lapply(.SD,
                      sum),
             .SDcols = "val",
             by = .(year,
                    month,
                    day)]

【问题讨论】:

    标签: r data.table lapply


    【解决方案1】:

    我看新建data.table对象没有问题,可以用同名重写。

         dt <- dt[, lapply(.SD,
                          sum),
                 .SDcols = "val",
                 by = .(year,
                        month,
                        day)]
    

    根据此功能请求中的讨论:https://github.com/Rdatatable/data.table/issues/635。

    【讨论】:

    • 感谢问题链接。我在data.table 上似乎落后了几年。重复的行似乎是使用:= 通过引用对val 列进行分组和修改的结果。有没有办法将该操作包含在内,使用lapply 到data.table 链中?我可以创建新的data.table,但是如果我可以链接它并且data.table 的行根据分组by 变量进行修改,流程会更好。
    • 它们没有重复。它们与您的初始 data.table 中的行相同。您可以使用 dt
    • 你是对的,它们不是重复的。 lapply 为分组变量中的所有行创建具有相同值的新列 val。我将继续阅读并暂时分配给一个新变量...
    • 我现在明白了我所追求的不可能。我在参考语义文档中重新创建了示例,并得到了与我在自己的分析中遇到的结果相同的结果。除此之外,@Vladimir Volokhonsky 提供的链接也证实了这一点。
    猜你喜欢
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 2019-12-06
    相关资源
    最近更新 更多