在 dplyr 中使用动态位置数创建滞后/超前变量

Ric*_*c S 2 r lag dplyr

我正在寻找一种方法来生成从具有动态位置数(参数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
Run Code Online (Sandbox Code Playgroud)

更实际地说,我的想法是我想创建一个var3具有以下条件的变量:

  • 如果n_steps == 0, var3=var1
  • if n_steps > 0, var3= +步数var1的滞后var2n_steps

我尝试了以下代码

df %>% 
  group_by(id) %>% 
  mutate(var3 = ifelse(n_steps == 0, var1, var1 + lag(var2, n = n_steps)))
Run Code Online (Sandbox Code Playgroud)

返回以下错误

错误:mutate()输入有问题var3n必须是非负整数标量,而不是长度为 6 的双精度向量。输入 var3ifelse(n_steps == 0, var1, var1 + lag(var2, n = n_steps))。错误发生在group 1:id = 1。运行rlang::last_error()看看错误发生在哪里。

我的理解是:参数n需要一个标量值。我想引用当前行,但我没有在 SO 上找到任何有关它的信息。另外,我可以为 假定的每个值创建 N 个新变量n_steps,但我正在寻找一种动态使用这些滞后列而不实际创建它们的方法。我怎样才能实现它?

预期输出:

      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
Run Code Online (Sandbox Code Playgroud)

Bel*_*Eqn 5

尝试这个?

df %>% 
  mutate(var3 = ifelse(n_steps == 0, var1, var1 + var2[row_number()-n_steps]))
Run Code Online (Sandbox Code Playgroud)