如何根据行索引对数据帧执行滞后/超前

时间:2020-07-09 09:04:01

标签: r

如何根据行的值(或行索引)滞后/超前数据帧,以实现以下输出。

这是一个示例数据集:

id <- c(1,1,1,1,1,1)
a <- c("X1","Mar-20","X2","X3","Apr-20", "X4")

test <- data.frame(id,a)

所需的输出:

id|a
1 |Mar-20
1 |Mar-20
1 |Mar-20
1 |Apr-20
1 |Apr-20
1 |Apr-20

3 个答案:

答案 0 :(得分:2)

使用dplyrstringr假设问题中显示的模式对所有数据都是一致的。

library(dplyr)
library(stringr)

test %>% 
  mutate(a = case_when(lead(str_detect(a, "-")) ~ lead(a),
                       lag(str_detect(a, "-")) ~ lag(a),
                       TRUE ~ a))
#>   id      a
#> 1  1 Mar-20
#> 2  1 Mar-20
#> 3  1 Mar-20
#> 4  1 Apr-20
#> 5  1 Apr-20
#> 6  1 Apr-20

reprex package(v0.3.0)于2020-07-09创建

答案 1 :(得分:1)

您可以根据df的行数创建分组变量,然后将第一个和第三个实例替换为第二个,即

with(test, ave(a, rep(seq(nrow(test)/3), each = 3), FUN = function(i){i[c(1, 3)] <- i[2]; i}))
#[1] Mar-20 Mar-20 Mar-20 Apr-20 Apr-20 Apr-20

答案 2 :(得分:1)

我认为这是解决此问题的更一般的方法。

您可以使用以下功能为要修改的列中的每个值指定提前量(或滞后,如果为负)。从某种意义上说,这可以提前/滞后。

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))