如何根据行的值(或行索引)滞后/超前数据帧,以实现以下输出。
这是一个示例数据集:
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
答案 0 :(得分:2)
使用dplyr
和stringr
假设问题中显示的模式对所有数据都是一致的。
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))