Я думаю, что это более общее решение этой проблемы.
Вы можете использовать следующую функцию, чтобы указать количество опережений (или запаздываний, если они отрицательны) для каждого значения в столбце, который нужно изменить. В некотором смысле это векторизует опережение / отставание.
lead_lag <- function(lead_lag_this, by_this, default = NA)
{
diag(sapply(by_this, function(x) if(x == 0) lead_lag_this
else if(x < 0) lead(lead_lag_this, -x, default)
else if(x > 0) lag(lead_lag_this, x, default)))
}
Так, например, предположим, что мы добавляем столбец к вашему фрейму данных, который определяет опережение или отставание:
test$leadlag <- c(-1, 0, 1, -1, 0, 1)
test
#> id a leadlag
#> 1 1 X1 -1
#> 2 1 Mar-20 0
#> 3 1 X2 1
#> 4 1 X3 -1
#> 5 1 Apr-20 0
#> 6 1 X4 1
Тогда мы можем используйте столбец leadlag
для опережения или отставания столбца a
следующим образом:
test %>% mutate(new_a = lead_lag(a, leadlag))
#> id a leadlag new_a
#> 1 1 X1 -1 Mar-20
#> 2 1 Mar-20 0 Mar-20
#> 3 1 X2 1 Mar-20
#> 4 1 X3 -1 Apr-20
#> 5 1 Apr-20 0 Apr-20
#> 6 1 X4 1 Apr-20
Конечно, если вы просто хотите создать повторяющийся шаблон, например c(-1, 0, 1)
, на основе номера строки (без указания столбец leadlag
) вы можете сделать
test %>% mutate(new_a = lead_lag(a, (row_number() - 1) %% 3 - 1))