изменение data.table по ссылке с помощью «lapply» и «by» создает повторяющиеся строки для группировки столбцов - PullRequest
0 голосов
/ 06 ноября 2018

Возможно, об этом уже спрашивали, и я просмотрел Ссылочная семантика , но я не могу найти ответ. ТАК также предложил пересмотреть мой заголовок, так что я буду в порядке, если кто-то разместит ссылку на ответ!

У меня есть 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)]

1 Ответ

0 голосов
/ 06 ноября 2018

Я не вижу никаких проблем при создании нового объекта data.table, вы можете переписать его с тем же именем.

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

Теперь вы не можете изменить количество строк в таблице data.table без переписывания, как dt<-unique(dt) в соответствии с обсуждением в этом запросе: https://github.com/Rdatatable/data.table/issues/635.

...