通过用'lapply'和'by'引用修改data.table创建重复的行以对列进行分组

时间:2018-11-06 02:50:56

标签: r data.table lapply

这可能是以前问过的,我已经浏览了Reference semantics,但似乎找不到答案。 SO还建议修改我的标题,所以如果有人发布指向答案的链接,我会没事的!

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

但是,在SCENARIO 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)]

1 个答案:

答案 0 :(得分:1)

在创建新的data.table对象时没有发现任何问题,您可以使用相同的名称进行重写。

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

现在,根据此功能请求https://github.com/Rdatatable/data.table/issues/635中的讨论,如果不像dt<-unique(dt)那样重写,就无法更改data.table中的行数。

相关问题