tidyr/dplyr: 将自定义多参数函数应用于滚动 windows

tidyr/dplyr: Apply custom multi-param function to rolling windows

我想将某些列的滚动 window 传递给一个自定义函数,并传递其他列的实际值。

给定示例数据和示例函数。 将 myfunc 应用于变量 var1var2 的大小为 3 的滚动 windows,以及 param1param2 的第一个值.

示例: 对于第 2015-07-03 行,传递了 myfunc 函数:

示例数据

library(dplyr)

myfunc <- function(var1, param1, var2, param2){
  c(length(var1), length(var2), param1, param2)
}

d <- data_frame(date = seq(as.Date('2015-07-01'), as.Date('2015-07-12'), by = '1 day'))
d <- d %>%
  mutate(var1   = seq(1,2, length=12), 
         var2   = seq(3,6, length=12),
         param1 = rep(seq(1,3, length=3),4),
         param2 = rep(seq(11,13, length=3),4))

>d
  # A tibble: 12 x 5
  date       param1 param2  var1  var2
<date>      <dbl>  <dbl> <dbl> <dbl>
  1 2015-07-01      1     11  1     3   
2 2015-07-02      2     12  1.09  3.27
3 2015-07-03      3     13  1.18  3.55
4 2015-07-04      1     11  1.27  3.82
5 2015-07-05      2     12  1.36  4.09
6 2015-07-06      3     13  1.45  4.36
7 2015-07-07      1     11  1.55  4.64
8 2015-07-08      2     12  1.64  4.91
9 2015-07-09      3     13  1.73  5.18
10 2015-07-10      1     11  1.82  5.45
11 2015-07-11      2     12  1.91  5.73
12 2015-07-12      3     13  2     6   

期望的输出:

# A tibble: 12 x 4
date       param1 param2  res  
<date>      <dbl>  <dbl> <lst> 
1 2015-07-01      1     11  <..>     
2 2015-07-02      2     12  <..>   
3 2015-07-03      3     13  <..>   
4 2015-07-04      1     11  <..>   
5 2015-07-05      2     12  <..>   
6 2015-07-06      3     13  <..>  
7 2015-07-07      1     11  <..>   
8 2015-07-08      2     12  <..>   
9 2015-07-09      3     13  <..>  
10 2015-07-10      1     11  <..>   
11 2015-07-11      2     12  <..>   
12 2015-07-12      3     13  <..>     

2015-07-03d$res 的内容是 3,3,3,13

这是一个使用 zoo 包中的 rollapply 函数的想法。我通过删除 length 对您的函数进行了轻微修改(这基本上使该函数变得不必要,但我将使用它仅供参考)因为我是通过 rollapply,即

 myfunc <- function(var1, param1, var2, param2) {
     c(var1, var2, param1, param2)
 }

library(zoo)
library(tidyverse)

d %>% 
 mutate(newvar1 = rollapply(var1, width = 3, FUN = length, partial = TRUE), 
        newvar2 = rollapply(var2, width = 3, FUN = length, partial = TRUE)) %>% 
 rowwise() %>% 
 mutate(res = list(myfunc(newvar1, newvar2, param1, param2)))
 #or mutate(res = list(c(newvar1, ...)))

这给出了,

# A tibble: 12 x 8
   date        var1  var2 param1 param2 newvar1 newvar2 res      
   <date>     <dbl> <dbl>  <dbl>  <dbl>   <int>   <int> <list>   
 1 2015-07-01  1     3         1     11       2       2 <dbl [4]>
 2 2015-07-02  1.09  3.27      2     12       3       3 <dbl [4]>
 3 2015-07-03  1.18  3.55      3     13       3       3 <dbl [4]>
 4 2015-07-04  1.27  3.82      1     11       3       3 <dbl [4]>
 5 2015-07-05  1.36  4.09      2     12       3       3 <dbl [4]>
 6 2015-07-06  1.45  4.36      3     13       3       3 <dbl [4]>
 7 2015-07-07  1.55  4.64      1     11       3       3 <dbl [4]>
 8 2015-07-08  1.64  4.91      2     12       3       3 <dbl [4]>
 9 2015-07-09  1.73  5.18      3     13       3       3 <dbl [4]>
10 2015-07-10  1.82  5.45      1     11       3       3 <dbl [4]>
11 2015-07-11  1.91  5.73      2     12       3       3 <dbl [4]>
12 2015-07-12  2     6         3     13       2       2 <dbl [4]>

第 3 行,

d2$res[3]
#[[1]]
#[1]  3  3  3 13

注意: 您可以在管道的末尾添加 select 语句并删除 newvar*