如何在 data.table 内添加滞后并导致更多变量(不包括 NA)的每个观察值?
How to add lag and lead to each observations for more variables excluding NAs within data.table?
我有一个 data.table 类似于:
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
但这会为没有 lead/lag 值的行引入 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
正如@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
我有一个 data.table 类似于:
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
但这会为没有 lead/lag 值的行引入 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
正如@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