使用动态位置数在 dplyr 中创建 lag/lead 变量
Create lag/lead variable in dplyr with dynamic number of position
我正在寻找一种方法来生成从具有动态位置数的滞后列派生的列(参数 n
),这意味着这个新列应该作为参数 n
存储在另一列中的值(有关文档,请参阅 lag
函数)。
示例数据:
set.seed(42)
df <- as_tibble(data.frame(
id = c(rep(1,6), rep(2,5), rep(3,6)),
n_steps = c(0,0,0,0,1,2,0,0,1:3,0,1:5),
var1 = sample(1:9, 17, replace = TRUE),
var2 = runif(17, 1, 2)))
# A tibble: 17 x 4
id n_steps var1 var2
<dbl> <dbl> <int> <dbl>
1 1 0 1 1.08
2 1 0 5 1.51
3 1 0 1 1.39
4 1 0 9 1.91
5 1 1 4 1.45
6 1 2 2 1.84
7 2 0 1 1.74
8 2 0 8 1.81
9 2 1 7 1.39
10 2 2 4 1.69
11 2 3 9 1.00
12 3 0 5 1.83
13 3 1 4 1.01
14 3 2 2 1.21
15 3 3 3 1.91
16 3 4 9 1.61
17 3 5 9 1.38
更实际地说,我的想法是我想创建一个具有以下条件的变量var3
:
- if
n_steps == 0
, var3
= var1
- 如果
n_steps > 0
,var3
= var1
+ var2
滞后 n_steps
步
我试过下面的代码
df %>%
group_by(id) %>%
mutate(var3 = ifelse(n_steps == 0, var1, var1 + lag(var2, n = n_steps)))
其中returns出现以下错误
Error: Problem with mutate()
input var3
. n
must be a
nonnegative integer scalar, not a double vector of length 6. Input
var3
is ifelse(n_steps == 0, var1, var1 + lag(var2, n = n_steps))
.
The error occured in group 1: id = 1. Run rlang::last_error()
to
see where the error occurred.
我明白了:参数 n
需要一个标量值。我想参考当前行,但我没有在 SO 上找到任何相关信息。此外,我可以为 n_steps
假定的每个值创建 N 个新变量,但我一直在寻找一种动态使用这些滞后列而不实际创建它们的方法。我怎样才能实现它?
预期输出:
id n_steps var1 var2 var3
1 1 0 1 1.08 1
2 1 0 5 1.51 5
3 1 0 1 1.39 1
4 1 0 9 1.91 9
5 1 1 4 1.45 5.91
6 1 2 2 1.84 3.91
7 2 0 1 1.74 1
8 2 0 8 1.81 8
9 2 1 7 1.39 8.81
10 2 2 4 1.69 5.81
11 2 3 9 1.00 10.81
12 3 0 5 1.83 5
13 3 1 4 1.01 5.83
14 3 2 2 1.21 3.83
15 3 3 3 1.91 4.83
16 3 4 9 1.61 10.83
17 3 5 9 1.38 10.83
试试这个?
df %>%
mutate(var3 = ifelse(n_steps == 0, var1, var1 + var2[row_number()-n_steps]))
这是一个带有 for
循环的解决方案:
df <- df %>%
mutate(var3 = NA)
for (i in 1:nrow(df)){
df$var3[i] = df$var1[i] + df$n_steps[i] * df$var2[i - df$n_steps[i]]
}
df
# A tibble: 17 x 5
id n_steps var1 var2 var3
<dbl> <dbl> <int> <dbl> <dbl>
1 1 0 1 1.08 1
2 1 0 5 1.51 5
3 1 0 1 1.39 1
4 1 0 9 1.91 9
5 1 1 4 1.45 5.91
6 1 2 2 1.84 5.81
7 2 0 1 1.74 1
8 2 0 8 1.81 8
9 2 1 7 1.39 8.81
10 2 2 4 1.69 7.62
11 2 3 9 1.00 14.4
12 3 0 5 1.83 5
13 3 1 4 1.01 5.83
14 3 2 2 1.21 5.67
15 3 3 3 1.91 8.50
16 3 4 9 1.61 16.3
17 3 5 9 1.38 18.2
lag 不起作用的原因是它被矢量化了,但是矢量化对于你的问题来说是不可能的。
我正在寻找一种方法来生成从具有动态位置数的滞后列派生的列(参数 n
),这意味着这个新列应该作为参数 n
存储在另一列中的值(有关文档,请参阅 lag
函数)。
示例数据:
set.seed(42)
df <- as_tibble(data.frame(
id = c(rep(1,6), rep(2,5), rep(3,6)),
n_steps = c(0,0,0,0,1,2,0,0,1:3,0,1:5),
var1 = sample(1:9, 17, replace = TRUE),
var2 = runif(17, 1, 2)))
# A tibble: 17 x 4
id n_steps var1 var2
<dbl> <dbl> <int> <dbl>
1 1 0 1 1.08
2 1 0 5 1.51
3 1 0 1 1.39
4 1 0 9 1.91
5 1 1 4 1.45
6 1 2 2 1.84
7 2 0 1 1.74
8 2 0 8 1.81
9 2 1 7 1.39
10 2 2 4 1.69
11 2 3 9 1.00
12 3 0 5 1.83
13 3 1 4 1.01
14 3 2 2 1.21
15 3 3 3 1.91
16 3 4 9 1.61
17 3 5 9 1.38
更实际地说,我的想法是我想创建一个具有以下条件的变量var3
:
- if
n_steps == 0
,var3
=var1
- 如果
n_steps > 0
,var3
=var1
+var2
滞后n_steps
步
我试过下面的代码
df %>%
group_by(id) %>%
mutate(var3 = ifelse(n_steps == 0, var1, var1 + lag(var2, n = n_steps)))
其中returns出现以下错误
Error: Problem with
mutate()
inputvar3
.n
must be a nonnegative integer scalar, not a double vector of length 6. Inputvar3
isifelse(n_steps == 0, var1, var1 + lag(var2, n = n_steps))
. The error occured in group 1: id = 1. Runrlang::last_error()
to see where the error occurred.
我明白了:参数 n
需要一个标量值。我想参考当前行,但我没有在 SO 上找到任何相关信息。此外,我可以为 n_steps
假定的每个值创建 N 个新变量,但我一直在寻找一种动态使用这些滞后列而不实际创建它们的方法。我怎样才能实现它?
预期输出:
id n_steps var1 var2 var3
1 1 0 1 1.08 1
2 1 0 5 1.51 5
3 1 0 1 1.39 1
4 1 0 9 1.91 9
5 1 1 4 1.45 5.91
6 1 2 2 1.84 3.91
7 2 0 1 1.74 1
8 2 0 8 1.81 8
9 2 1 7 1.39 8.81
10 2 2 4 1.69 5.81
11 2 3 9 1.00 10.81
12 3 0 5 1.83 5
13 3 1 4 1.01 5.83
14 3 2 2 1.21 3.83
15 3 3 3 1.91 4.83
16 3 4 9 1.61 10.83
17 3 5 9 1.38 10.83
试试这个?
df %>%
mutate(var3 = ifelse(n_steps == 0, var1, var1 + var2[row_number()-n_steps]))
这是一个带有 for
循环的解决方案:
df <- df %>%
mutate(var3 = NA)
for (i in 1:nrow(df)){
df$var3[i] = df$var1[i] + df$n_steps[i] * df$var2[i - df$n_steps[i]]
}
df
# A tibble: 17 x 5
id n_steps var1 var2 var3
<dbl> <dbl> <int> <dbl> <dbl>
1 1 0 1 1.08 1
2 1 0 5 1.51 5
3 1 0 1 1.39 1
4 1 0 9 1.91 9
5 1 1 4 1.45 5.91
6 1 2 2 1.84 5.81
7 2 0 1 1.74 1
8 2 0 8 1.81 8
9 2 1 7 1.39 8.81
10 2 2 4 1.69 7.62
11 2 3 9 1.00 14.4
12 3 0 5 1.83 5
13 3 1 4 1.01 5.83
14 3 2 2 1.21 5.67
15 3 3 3 1.91 8.50
16 3 4 9 1.61 16.3
17 3 5 9 1.38 18.2
lag 不起作用的原因是它被矢量化了,但是矢量化对于你的问题来说是不可能的。