Clo*_*t X 5 variables r dplyr data-cleaning tidyverse
我有一个虚拟变量,如下所示:
df <- data.frame(year = seq(1990, 1997, 1),
x = c(1, 0, 0, 0, 1, 1, 0, 0))
year x
1990 1
1991 0
1992 0
1993 0
1994 1
1995 1
1996 0
1997 0
Run Code Online (Sandbox Code Playgroud)
如果前三年中任何一年的值非零,我想创建一个y等于的虚拟值。预期结果:1x
year x y
1990 1 NA
1991 0 NA
1992 0 1
1993 0 0
1994 1 1
1995 1 1
1996 0 1
1997 0 1
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?dplyr优选解决方案。
如果您确定需要 3 个值,您可以这样做:
library(dplyr)
df %>% mutate(y = sign((x > 0) + (lag(x) > 0) + (lag(x, 2) > 0)))
#> year x y
#> 1 1990 1 NA
#> 2 1991 0 NA
#> 3 1992 0 1
#> 4 1993 0 0
#> 5 1994 1 1
#> 6 1995 1 1
#> 7 1996 0 1
#> 8 1997 0 1
Run Code Online (Sandbox Code Playgroud)
但如果您想选择,更通用的解决方案n是:
n <- 3
df %>% mutate(y = sign(purrr::reduce(seq(n) - 1, ~ .x + (lag(x, .y)))))
#> year x y
#> 1 1990 1 NA
#> 2 1991 0 NA
#> 3 1992 0 1
#> 4 1993 0 0
#> 5 1994 1 1
#> 6 1995 1 1
#> 7 1996 0 1
#> 8 1997 0 1
Run Code Online (Sandbox Code Playgroud)
zoo这是使用s的解决方案rollapply:
library(dplyr)
library(zoo)
df %>%
mutate(y = rollapply(x, width = 3, \(x) any(x > 0), align = "right", fill = NA)*1)
Run Code Online (Sandbox Code Playgroud)
或者更简洁地感谢@G。格洛腾迪克:
library(dplyr)
library(zoo)
df %>% mutate(y = + rollapplyr(x > 0, 3, any, fill = NA) )
Run Code Online (Sandbox Code Playgroud)
year x y
1 1990 1 NA
2 1991 0 NA
3 1992 0 1
4 1993 0 0
5 1994 1 1
6 1995 1 1
7 1996 0 1
8 1997 0 1
Run Code Online (Sandbox Code Playgroud)