首页 > 解决方案 > tidyr/dplyr:将自定义多参数函数应用于滚动窗口

问题描述

我想将某些列的滚动窗口传递给自定义函数,以及其他列的实际值。

给定示例数据和示例函数。应用于变量和myfunc的大小为 3 的滚动窗口,以及和的第一个值。var1var2param1param2

示例:对于传递函数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-03的内容在d$res哪里3,3,3,13

标签: rtidyrrolling-computation

解决方案


这是一个使用包中的rollapply函数的想法zoo。我通过删除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]>

第三排在哪里,

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

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


推荐阅读