每个日期有多个观测值的唯一日期移动平均线

Moving Average by Unique Date with multiple observations per date

我有一个数据集,每个日期可能包含多个观察结果。因此,date1 可能有 5 个观察值,date2 有 2 个观察值,group3 有 1 个观察值。

我想计算移动平均值 - 按日期 - 重要的是而不是 summarising/reducing' 行数。那就是在上面的这个例子中,我仍然有 8 行数据,并且在它旁边的一列中我会有那个日期的滚动平均价格我发现这具有挑战性,因为当我使用 ZOO 包中的典型滚动功能时,它会逐行-行,我不知道如何让它在 DATE

之前跳过

例如第一步通常是:

df %>% 
 groupy_by(DATE) %>% 
 summarise(mean_daily_price = mean(price)) %>% 
 ungroup() %>% 
 arrange(Date) %>% 
 mutate( ra = rollapply(price, 2, mean, partial=T)   

--- 但是总结让我失去了行。

      library(dplyr)
      library(zoo)


            DF = structure(list(Date = c("Jan-13", "Jan-13", "Jan-13", "Jan-13",  "Jan-13", "Jul-14", "Jul-14", "Oct-16"), Price = c(100L, 200L,  300L, 1000L, 400L, 150L, 50L, 600L), Average.by.Date = c(400L,  400L, 400L, 400L, 400L, 100L, 100L, 600L), Moving_Average_Size_2 = c(NA,  NA, NA, NA, NA, 250L, 250L, 350L)), .Names = c("Date", "Price", "Average.by.Date", "Moving_Average_Size_2"), class = "data.frame", row.names = c(NA, 
-8L))

在下面的代码中,我们使用mutate而不是summarise来添加mean_daily_price,这样我们就保留了数据框的所有行。然后,在最后的 mutate 中我们 运行 rollapply 仅在 mean_daily_price 的唯一值上,然后使用 tablerep 重复按每个 Date.

的行数输出 rollapply
DF %>% 
  arrange(Date) %>% 
  group_by(Date) %>% 
  mutate(mean_daily_price = mean(Price)) %>% 
  ungroup() %>% 
  mutate(ra = rep(rollapply(unique(mean_daily_price), 2, mean, fill=NA, align="right"), 
                  table(Date)[order(unique(Date))]))
    Date Price Average.by.Date Moving_Average_Size_2 mean_daily_price    ra
1 Jan-13   100             400                    NA              400    NA
2 Jan-13   200             400                    NA              400    NA
3 Jan-13   300             400                    NA              400    NA
4 Jan-13  1000             400                    NA              400    NA
5 Jan-13   400             400                    NA              400    NA
6 Jul-14   150             100                   250              100   250
7 Jul-14    50             100                   250              100   250
8 Oct-16   600             600                   350              600   350

我认为最安全的方法需要分两步进行——通过 Date 计算滚动平均值,然后将它们合并回去(此处仍使用 dplyr

rolledAvg <-
  DF %>%
  group_by(Date) %>%
  summarise(mean_daily_price = mean(Price)) %>%
  ungroup() %>%
  arrange(Date) %>%
  mutate( ra = rollapply(mean_daily_price
                         , 2
                         , mean
                         , partial=T
                         , fill = NA))

left_join(DF, rolledAvg)

给出:

    Date Price Average.by.Date Moving_Average_Size_2 mean_daily_price  ra
1 Jan-13   100             400                    NA              400 250
2 Jan-13   200             400                    NA              400 250
3 Jan-13   300             400                    NA              400 250
4 Jan-13  1000             400                    NA              400 250
5 Jan-13   400             400                    NA              400 250
6 Jul-14   150             100                   250              100 350
7 Jul-14    50             100                   250              100 350
8 Oct-16   600             600                   350              600 600

我在对另一个答案的评论中看到,您认为第一个 ra 不应该是 250 —— 如果是这样,请将调用中的计算更改为 rollapply。现在,它似乎表现得像 expected/documented。所以,如果你想要不同的东西,你需要解释你想要的改变(可能是一个单独的问题)。

另一个警告,对于偶然发现这一点的任何其他读者来说尤其重要:当前的方法将连续的日期条目视为等距的,无论它们实际上相距多远。如果这能满足您的需要,那就太好了。但是,在许多用例中,您可能需要注意测量之间的实际时间量。

同样,当前的方法丢失了所有关于测量次数的信息,可能值得考虑一种按观察次数加权的方法(除非您乐于相信每天计算出的平均值)。