R按时间序列在信号后的第二天提取

时间:2019-07-19 10:45:46

标签: r dplyr time-series

在我的示例中,我有一个包含3列的数据框:日期,信号和值。现在,我要突变一个新列,该列取决于信号。

如果前一天(ifelse(lag(signal) == 1)有信号,请在接下来的两天给我(else = NA)。

使用此代码,我只能在第二天获得。但是我也想拥有第二个。

df %>% mutate(calculation = ifelse(lag(signal) == 1,
                                   value,
                                   NA))

这是我的示例数据:

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

# A tibble: 11 x 4
   date       signal value  
   <date>      <dbl> <int>   
 1 2019-07-17      0     1   
 2 2019-07-18      1     7   
 3 2019-07-19      0     5   
 4 2019-07-20      0     4   
 5 2019-07-21      0    10   
 6 2019-07-22      0     2   
 7 2019-07-23      1     9   
 8 2019-07-24      0     3   
 9 2019-07-25      0    11   
10 2019-07-26      0     8   
11 2019-07-27      0     6   

这是我想要的输出:

# A tibble: 11 x 4
   date       signal value     value_new
   <date>      <dbl> <int>      <dbl>
 1 2019-07-17      0     1       NA   
 2 2019-07-18      1     7       NA   
 3 2019-07-19      0     5       5
 4 2019-07-20      0     4       4   
 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       3
 9 2019-07-25      0    11       11   
10 2019-07-26      0     8       NA   
11 2019-07-27      0     6       NA  

我希望有一个动态的解决方案,因为我不仅希望接下来的两天,而且希望连续七天。

该解决方案也应适用于重叠事件。

您能帮我解决我的问题吗?

1 个答案:

答案 0 :(得分:1)

df %>% 
   mutate(calculation=ifelse( (lag(signal, 2) == 1) | (lag(signal) == 1), value, NA))

这当然不够好,因为您想要一个可扩展的解决方案。让我们更加努力:

anylag <- function(x, n) {
  l <- lapply(1:n, function(i) lag(x, i) == 1)
  Reduce("|", l)
}

df %>% mutate(calculation=ifelse(anylag(signal, 3), value, NA))

Result:

# A tibble: 11 x 4
   date       signal value calculation
   <date>      <dbl> <int>       <int>
 1 2019-07-19      0     4          NA
 2 2019-07-20      1     8          NA
 3 2019-07-21      0    11          11
 4 2019-07-22      0    10          10
 5 2019-07-23      0     7           7
 6 2019-07-24      0     1          NA
 7 2019-07-25      1     3          NA
 8 2019-07-26      0     9           9
 9 2019-07-27      0     2           2
10 2019-07-28      0     6           6
11 2019-07-29      0     5          NA

注意。您的signal类型为double。由于浮点精度有限,因此您应该从不使用==%in%比较双精度数。将其转换为整数或使用all_equal()。考虑一下:

> 3*.1 / 3 * 10 
[1] 1
> 3*.1 / 3 * 10 == 1
[1] FALSE
> all.equal(3*.1 / 3 * 10, 1)
[1] TRUE