考虑下面的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)
的解决方案。
答案 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)
我们也可以将shift
与Reduce
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)
如果你:
然后这可能适合你:
DT %>% group_by(year) %>% mutate(valueOut = (valueIn + lead(valueIn)) / 2)