如何在data.table中对每个变量添加滞后和超前值,排除NA值?

4

我可以帮助你进行翻译。以下是与此类似的数据表:

library(data.table)
mydt <- data.table(id = LETTERS[1:6], x = 1:6, y = 2:3) 
> mydt
   id x y
1:  A 1 2
2:  B 2 3
3:  C 3 2
4:  D 4 3
5:  E 5 2
6:  F 6 3

我希望用每个观察值的前一个和后一个观察值之和来替换值列 (即 x[-1] + x + x[1])。我可以使用神奇的shift()功能来完成这样的操作。

cols <- c('x', 'y')
mydt[
    ,
    (cols) := shift(.SD, 1) + .SD + shift(.SD, 1, type = 'lead'),
    .SDcols = cols
][]
   id  x  y
1:  A NA NA
2:  B  6  7
3:  C  9  8
4:  D 12  7
5:  E 15  8
6:  F NA NA

但是这会在没有前/后值的行中引入NA。我该如何修改计算以仅对这些行使用可用的两个值(例如na.rm = TRUE)?以便输出为

   id  x  y
1:  A  3  5
2:  B  6  7
3:  C  9  8
4:  D 12  7
5:  E 15  8
6:  F 11  5

我尝试使用sum(..., na.rm = TRUE)代替+运算符,但是这会导致错误:Error in sum(shift(.SD, 1), .SD, shift(.SD, 1, type = "lead"), na.rm = TRUE) : invalid 'type' (list) of argument

我还尝试了以下方法,但显然得到了其他结果。

mydt[
    ,
    (cols) := lapply(
        .SD, 
        function(x) sum(shift(x, 1), x, shift(x, 1, type = 'lead'), na.rm = TRUE)
    ),
    .SDcols = cols
][]
   id   x  y
1:  A 126 90
2:  B 126 90
3:  C 126 90
4:  D 126 90
5:  E 126 90
6:  F 126 90

也许可以这样编程:mydt[, (cols):=lapply(.SD, function(x) shift(x, fill=0)+x+shift(x, type="lead", fill=0)) , .SDcols= cols] - akrun
1
@akrun,你可以发表回答,因为我不会。顺便说一句,@jan,你在data.table方面取得了不错的进展:) - David Arenburg
谢谢,我就差一点了...请将其发布为答案,以便我可以接受它。 - janosdivenyi
@DavidArenburg 没关系。你先想出了这个主意,所以你可以发布它。 - akrun
在这种情况下,我建议@jan回答自己,因为他做了大部分的工作。无论如何,我都不会发帖。 - David Arenburg
1个回答

1
正如 @akrun 和 @DavidArenburg 指出的那样,shift 函数有一个 fill 参数,可以解决这个问题。
cols <- c('total_open', 'total_send')
mydt[
    ,
    (cols) := shift(.SD, 1, fill = 0) + .SD + shift(.SD, 1, type = 'lead', fill = 0),
    .SDcols = cols
][]
   id  x y
1:  A  3 5
2:  B  6 7
3:  C  9 8
4:  D 12 7
5:  E 15 8
6:  F 11 5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接