Эффективен ли мой способ дублирования строк в data.table?

У меня есть ежемесячные данные в одной таблице data.table и годовые данные в другой таблице data.table , и теперь я хочу сопоставить годовые данные к соответствующему наблюдению в ежемесячных данных.

Мой подход заключается в следующем: дублирую годовые данные для каждого месяца, а затем объединяю ежемесячные и годовые данные. А теперь у меня вопрос по поводу дублирования строк. Я знаю, как это сделать, но не уверен, что это лучший способ сделать это, поэтому некоторые мнения были бы замечательными.

Вот примерная data.table DT для моих годовых данных и того, как я в настоящее время дублирую:

library(data.table)
DT <- data.table(ID = paste(rep(c("a", "b"), each=3), c(1:3, 1:3), sep="_"),
                    values = 10:15,
                    startMonth = seq(from=1, by=2, length=6),
                    endMonth = seq(from=3, by=3, length=6))
DT
      ID values startMonth endMonth
[1,] a_1     10          1        3
[2,] a_2     11          3        6
[3,] a_3     12          5        9
[4,] b_1     13          7       12
[5,] b_2     14          9       15
[6,] b_3     15         11       18
#1. Alternative
DT1 <- DT[, list(MONTH=startMonth:endMonth), by="ID"]
setkey(DT,  ID)
setkey(DT1, ID)
DT1[DT]
ID MONTH values startMonth endMonth
a_1     1     10          1        3
a_1     2     10          1        3
a_1     3     10          1        3
a_2     3     11          3        6
[...]

Последнее соединение - это именно то, что я хочу. Однако DT [, list (MONTH = startMonth: endMonth), by = "ID"] уже делает все, что я хочу, кроме добавления других столбцов в DT , поэтому мне было интересно, Я мог избавиться от последних трех строк в моем коде, то есть от операций setkey и join . Оказывается, вы можете просто сделать следующее:

#2. Alternative: More intuitiv and just one line of code
DT[, list(MONTH=startMonth:endMonth, values, startMonth, endMonth), by="ID"]
 ID MONTH values startMonth endMonth
a_1    1     10          1        3
a_1    2     10          1        3
a_1    3     10          1        3
a_2    3     11          3        6
...

Это, однако, работает только потому, что я жестко запрограммировал имена столбцов в выражение list . В моих реальных данных я не знаю заранее имена всех столбцов, поэтому мне было интересно, могу ли я просто указать data.table , чтобы вернуть столбец MONTH , который я вычисляю, как показано выше, и все остальные столбцы DT . .SD , похоже, справился с задачей, но:

DT[, list(MONTH=startMonth:endMonth, .SD), by="ID"]
Error in `[.data.table`(DT, , list(YEAR = startMonth:endMonth, .SD), by = "ID") : 
  maxn (4) is not exact multiple of this j column's length (3)

Подводя итог, я знаю, как это было сделано, но мне просто было интересно, лучший ли это способ сделать это, потому что я ' m все еще немного борется с синтаксисом data.table и часто читает в сообщениях и в вики, что есть хорошие и плохие способы делать что-то. Кроме того, я не совсем понимаю, почему я получаю сообщение об ошибке при использовании .SD . Я думал, что это простой способ сообщить data.table , что вам нужны все столбцы. Что я упускаю?

20
задан Christoph_J 4 November 2011 в 13:28
поделиться