Data.table:使用组移位数据的操作

时间:2016-11-22 14:59:20

标签: r data.table

考虑下面的table{ table-layout:auto; width: 100%; border-collapse: collapse; } td{ border:1px solid red; width: 16.6666%; } td:first-child{ width: calc(16.6666% * 0.5); } td:last-child{ width: calc(16.6666% * 2); }

data.table

我想要以下输出:

DT <- data.table(year    = c(2011,2012,2013,2011,2012,2013,2011,2012,2013),
                 level   = c(137,137,137,136,136,136,135,135,135),
                 valueIn = c(13,30,56,11,25,60,8,27,51))

换句话说,我想根据DT <- data.table(year = c(2011,2012,2013,2011,2012,2013,2011,2012,2013), level = c(137,137,137,136,136,136,135,135,135), valueIn = c(13,30,56, 11,25,60, 8,27,51), valueOut = c(12,27.5,58, 9.5,26,55.5, NA,NA,NA)) 计算操作(valueIn[level] - valueIn[level-1]) / 2。例如,第一个值的计算方式如下:year

目前,我使用(13+11)/2=12循环执行此操作,在其中为每个for创建data.table个子集:

level

这很丑陋且非常慢,所以我正在寻找一种更好,更快,levelDtList <- list() levels <- sort(DT$level, decreasing = FALSE) for (this.level in levels) { levelDt <- DT[level == this.level] if (this.level == min(levels)) { valueOut <- NA } else { levelM1Data <- levelDtList[[this.level - 1]] valueOut <- (levelDt$valueIn + levelM1Data$valueIn) / 2 } levelDt$valueOut <- valueOut levelDtList[[this.level]] <- levelDt } datatable <- rbindlist(levelDtList) 的解决方案。

3 个答案:

答案 0 :(得分:5)

使用shift - 函数与type = 'lead'获取下一个值,求和除以2:

DT[, valueOut := (valueIn + shift(valueIn, type = 'lead'))/2, by = year]

你得到:

   year level valueIn valueOut
1: 2011   137      13     12.0
2: 2012   137      30     27.5
3: 2013   137      56     58.0
4: 2011   136      11      9.5
5: 2012   136      25     26.0
6: 2013   136      60     55.5
7: 2011   135       8       NA
8: 2012   135      27       NA
9: 2013   135      51       NA

指定shift - 函数的所有参数:

DT[, valueOut := (valueIn + shift(valueIn, n = 1L, fill = NA, type = 'lead'))/2, by = year]

答案 1 :(得分:2)

我们也可以将shiftReduce

一起使用
DT[, valueOut := Reduce(`+`, shift(valueIn, type = "lead", 0:1))/2, by = year]
DT
#   year level valueIn valueOut
#1: 2011   137      13     12.0
#2: 2012   137      30     27.5
#3: 2013   137      56     58.0
#4: 2011   136      11      9.5
#5: 2012   136      25     26.0
#6: 2013   136      60     55.5
#7: 2011   135       8       NA
#8: 2012   135      27       NA
#9: 2013   135      51       NA

更容易概括,因为shift可以采用'n'值的向量。

答案 2 :(得分:1)

如果你:

  • 不要介意使用dplyr
  • 年份是与您的物品相关的东西
  • 所示结构代表现实

然后这可能适合你:

DT %>% group_by(year) %>% mutate(valueOut = (valueIn + lead(valueIn)) / 2)