R 滚动表示非连续时间序列

R roll mean on a non continuous time serie

我想对最近 X 天进行滚动平均。 rollmean() 使用行来做到这一点。由于我使用的记录器有时会失败,而且数据也被清理过,所以时间序列不连续(行不一定代表恒定的时间差)。

一位同事提出了以下解决方案,效果很好。除了我的数据需要分组(在示例中按处理)。对于每一天,我想要每次治疗的最后 X 天的滚动平均值。

谢谢

 # making some example data
 # vector with days since the beginning of experiment

days <- 0:30
 
 # random values df1 <-   tibble::tibble(
     days_since_beginning = days,
     value_to_used = rnorm(length(days)),
     treatment = sample(letters[1],31,replace = TRUE)   )
 
 df2 <-   tibble::tibble(
     days_since_beginning = days,
     value_to_used = rnorm(length(days)),
     treatment = sample(letters[2],31,replace = TRUE)   )
 
 df <- full_join(df1, df2)
 
 # how long should be the period for mean

 time_period <- 10 # calculate for last 10 days
 
 
 df_mean <- df %>%    dplyr::mutate(
     # calculate rolling mean 
     roll_mean = purrr::map_dbl(
       .x = days_since_beginning,
       .f = ~ df %>% 
         # select only data for the last `time_period`
         dplyr::filter(days_since_beginning >= .x - time_period &
                         days_since_beginning <= .x) %>% 
         purrr::pluck("value_to_used") %>% 
         mean() %>% 
         return()
     )   )

这是过去 10 天治疗的平均值。 width 参数包括返回使用多少行的计算,因此它对应于 10 天而不是 10 行。这利用了宽度可以是向量的事实。

library(dplyr)
library(zoo)

df %>%
  group_by(treatment) %>%
  mutate(roll = rollapplyr(value_to_used, 
    seq_along(days_since_beginning) - findInterval(days_since_beginning - 10, days_since_beginning), 
    mean)) %>%
  ungroup

同一位同事提出了自己的解决方案:

df_mean <- 
  df %>%
  dplyr::group_by(treatment) %>% 
  tidyr::nest() %>% 
  dplyr::mutate(
    data_with_mean = purrr::map(
      .x = data,
      .f = ~ {
        dataset <- .x
        
        dataset %>% 
          dplyr::mutate(
            # calculate rolling mean 
            roll_mean = purrr::map_dbl(
              .x = days_since_beginning,
              .f = ~ dataset %>% 
                # select only data for the last `time_period`
                dplyr::filter(days_since_beginning >= .x - time_period &
                                days_since_beginning <= .x) %>% 
                purrr::pluck("value_to_used") %>% 
                mean() %>% 
                return()
            )) %>% 
          return()
        
      }
    )) %>% 
  dplyr::select(-data) %>% 
  tidyr::unnest(data_with_mean) %>% 
  dplyr::ungroup()

我将结果与G. Grothendieck的想法进行了比较,只有在我同事的代码中使用time_period和G. Grothendieck的代码中使用time_period + 1时才匹配。所以 time_period 的使用方式有所不同,我很困惑为什么会这样。