根据列的其他值,将多列添加到data.table的每周数据中的有效方法

时间:2018-07-24 14:01:57

标签: r data.table

我的数据具有以下结构:

a <- data.table(week = 1:52, price = 101:152)
a <- a[rep(1:nrow(a), each = 12),]
a$index_in_week <- 1:12

如何有效创建12个新列,这些新列将保存未来12周的价格值?因此,对于每周,我们有12行数据,索引列按周排列,因此它始终在range(1,12)之内。新列应包含从当前开始的接下来12周的价格,以1周为步长。例如,对于第1周,第一个新列的价格将在第1周到第12周,第2列的价格将在第2周到第13周,依此类推。 即,以下是创建前两列的方法:

a$price_for_week_1 <- apply(a, 1, function(y) {
  return(head(a[week == (y[[1]]+y[[3]]-1), price], 1))
})
a$price_for_week_2 <- apply(a, 1, function(y) {
  return(head(a[week == (y[[1]]+y[[3]]+0), price], 1))
})

以下是for循环的示例:

for (i in 1:12) {
  inside_i <- -2+i
  a[, paste0('PRICE_WEEK_', i) := apply(a, 1, function(y) {
    return(head(a[week == (y[[1]]+y[[3]] + inside_i), price], 1))
  })]
}

如我所见,这样做的方式(例如for循环或apply系列)会浪费太多时间,我需要效率。 data.table会是什么样?或者,由于所有列都是整数,所以会进行一些时髦的matrix操作?

P.s。抱歉,我无法拿出更好的头衔。

1 个答案:

答案 0 :(得分:1)

如果我理解正确,那么OP希望创建一个52周(行)的表格,此表格随后12周的价格水平打印。

为此,创建12 x 52 = 624行和index_in_week帮助列的data.table并不是必需的。 docendo discimus has suggested,将shift()函数应用于扩大的(624行)数据表。

相反,shift()函数可以直接应用于包含星期和价格(52行)的data.table。

library(data.table)
a <- data.table(week = 1:52, price = 101:152)
print(a, nrows = 20L)
    week price
 1:    1   101
 2:    2   102
 3:    3   103
 4:    4   104
 5:    5   105
---           
48:   48   148
49:   49   149
50:   50   150
51:   51   151
52:   52   152
a[, sprintf("wk%02i", 1:12) := shift(price, n = 0:11, type = "lead")]
print(a, nrows = 20L)
    week price wk01 wk02 wk03 wk04 wk05 wk06 wk07 wk08 wk09 wk10 wk11 wk12
 1:    1   101  101  102  103  104  105  106  107  108  109  110  111  112
 2:    2   102  102  103  104  105  106  107  108  109  110  111  112  113
 3:    3   103  103  104  105  106  107  108  109  110  111  112  113  114
 4:    4   104  104  105  106  107  108  109  110  111  112  113  114  115
 5:    5   105  105  106  107  108  109  110  111  112  113  114  115  116
---                                                                       
48:   48   148  148  149  150  151  152   NA   NA   NA   NA   NA   NA   NA
49:   49   149  149  150  151  152   NA   NA   NA   NA   NA   NA   NA   NA
50:   50   150  150  151  152   NA   NA   NA   NA   NA   NA   NA   NA   NA
51:   51   151  151  152   NA   NA   NA   NA   NA   NA   NA   NA   NA   NA
52:   52   152  152   NA   NA   NA   NA   NA   NA   NA   NA   NA   NA   NA