我有一个包含三个变量的数据集:日期、信号和值。现在我想改变一个新的列,它以信号为条件,并从值列计算。
如果前一天有信号(ifelse(lag(signal)==1
(,则计算接下来三天值的平均值。在本例中,我使用了以下表达式:
(value+lead(value)+lead(value,n = 2)) /3
.
所以我得到了我想要的:
set.seed(123)
df<-tibble(date=today()+0:10,
signal=c(0,1,0,0,0,0,1,0,0,0,0),
value= sample.int(n=11))
df%>%mutate(calculation=ifelse(lag(signal)==1,
(value+lead(value)+lead(value, n = 2)) /3,
NA))
# A tibble: 11 x 4
date signal value calculation
<date> <dbl> <int> <dbl>
1 2019-07-17 0 1 NA
2 2019-07-18 1 7 NA
3 2019-07-19 0 5 6.33
4 2019-07-20 0 4 NA
5 2019-07-21 0 10 NA
6 2019-07-22 0 2 NA
7 2019-07-23 1 9 NA
8 2019-07-24 0 3 7.33
9 2019-07-25 0 11 NA
10 2019-07-26 0 8 NA
11 2019-07-27 0 6 NA
但我的问题是我不只是想使用接下来的 3 天。我想用几天。因此,我想自动化代码并计算几列。也许带有类似应用函数的东西。
这是我想要的输出(在本例中为接下来的 5 天(:
date signal value calc_day_1 calc_day2 calc_day3 calc_day4 calc_day5
<date> <dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2019-07-17 0 1 NA NA
2 2019-07-18 1 7 NA NA
3 2019-07-19 0 5 5 (5+4)/2=4.5
4 2019-07-20 0 4 NA NA
5 2019-07-21 0 10 NA NA
6 2019-07-22 0 2 NA NA
7 2019-07-23 1 9 NA NA
8 2019-07-24 0 3 3 (3+11)/2=7
9 2019-07-25 0 11 NA NA
10 2019-07-26 0 8 NA NA
11 2019-07-27 0 6 NA NA
有人可以告诉我如何解决这个问题吗?
您可以使用rlang
包和purrr
包,如下所示:
library(tidyverse)
myfun <- paste0("if_else(lag(signal) == 1, map_dbl(1:n(), ~mean(value[.x - 1 + 1:",
1:5 ,"])), NA_real_)") %>%
setNames(paste0("calc_day", 1:5)) %>%
purrr::map(rlang::parse_expr)
df %>%
mutate(!!! myfun)
# A tibble: 11 x 8
date signal value calc_day1 calc_day2 calc_day3 calc_day4 calc_day5
<date> <dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2019-07-17 0 3 NA NA NA NA NA
2 2019-07-18 1 11 NA NA NA NA NA
3 2019-07-19 0 2 2 4 6 5.75 5.4
4 2019-07-20 0 6 NA NA NA NA NA
5 2019-07-21 0 10 NA NA NA NA NA
6 2019-07-22 0 5 NA NA NA NA NA
7 2019-07-23 1 4 NA NA NA NA NA
8 2019-07-24 0 9 9 8.5 6 6.25 NA
9 2019-07-25 0 8 NA NA NA NA NA
10 2019-07-26 0 1 NA NA NA NA NA
11 2019-07-27 0 7 NA NA NA NA NA
小解释:如果你只想要这些列(比如calc_day2
(,你可以执行以下操作:
df %>%
mutate(calc_day2 = if_else(lag(signal) == 1, map_dbl(1:n(), ~ mean(value[.x - 1 + 1:2])), NA_real_))
所以理论上你可以只复制这一行五次(每次用相应的数字替换2
(。
或者您使用rlang
包(另请参阅此问题(进行快捷方式:)。