使用动态位置数在 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

我试过下面的代码

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 不起作用的原因是它被矢量化了,但是矢量化对于你的问题来说是不可能的。