tidyr/dplyr: применить пользовательскую функцию с несколькими параметрами к скользящим окнам.

Я хотел бы передать скользящее окно некоторых столбцов пользовательской функции с фактическим значением других столбцов.

Учитывая пример данных и пример функции. Примените myfunc к скользящим окнам размера 3 переменных var1 и var2 и первым значениям param1 и param2.

Пример: Для строки 2015-07-03 передается функция myfunc:

  • var1=c(1.18,1.27, 1.36)
  • param1=3
  • var2=c(3.55,3.82,4.09)
  • param2=13

Пример данных

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


person Hedgehog    schedule 25.06.2018    source источник
comment
Разве length(var1) и var2 не всегда будут 3? Размер вашего скользящего окна 3 на 1 шаг?   -  person Sotos    schedule 08.02.2019


Ответы (1)


Вот идея, которая использует функцию 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]>

где для 3-й строки,

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

ПРИМЕЧАНИЕ. Вы можете добавить оператор select в конце канала и удалить столбцы newvar*.

person Sotos    schedule 08.02.2019