如何对含重复索引的xts对象核心数据进行高效聚合?
处理xts对象中的重复时间索引:高效聚合方案
问题背景
我有一个带重复时间索引的xts对象:
library(xts) x <- xts(1:5, as.Date(c("2024-04-19", "2024-04-19", "2024-04-20", "2024-04-21", "2024-04-21"))) x #> [,1] #> 2024-04-19 1 #> 2024-04-19 2 #> 2024-04-20 3 #> 2024-04-21 4 #> 2024-04-21 5
目前我只会用简单删除重复项的方式清理数据:
ind <- duplicated(zoo::index(x)) x[!ind, ] #> [,1] #> 2024-04-19 1 #> 2024-04-20 3 #> 2024-04-21 4
但我希望能通过指定聚合函数(比如均值、求和)来处理重复索引,返回xts对象,效果如下:
# 按均值聚合 xts_aggr_duplicates(x, "mean") #> [,1] #> 2024-04-19 1.5 #> 2024-04-20 3 #> 2024-04-21 4.5 # 按求和聚合 xts_aggr_duplicates(x, "sum") #> [,1] #> 2024-04-19 3 #> 2024-04-20 3 #> 2024-04-21 9
原本打算拆分对象、聚合后再合并,但这种方法处理大型数据效率极低,请问有没有高效的实现思路?
高效解决方案
方法1:利用xts/zoo原生的aggregate函数
xts继承自zoo,zoo的aggregate函数支持按索引分组聚合,底层是向量化操作,效率远高于手动拆分合并,直接返回xts对象:
xts_aggr_duplicates <- function(x, FUN) { aggregate(x, by = index(x), FUN = match.fun(FUN)) } # 测试均值聚合 xts_aggr_duplicates(x, "mean") #> [,1] #> 2024-04-19 1.5 #> 2024-04-20 3.0 #> 2024-04-21 4.5 # 测试求和聚合 xts_aggr_duplicates(x, "sum") #> [,1] #> 2024-04-19 3 #> 2024-04-20 3 #> 2024-04-21 9
方法2:结合data.table实现高速聚合
针对超大规模数据集,data.table的分组聚合性能更突出,只需将xts转成data.table完成聚合后,再转回xts:
library(data.table) xts_aggr_duplicates_dt <- function(x, FUN) { dt <- data.table( date = index(x), value = coredata(x) ) agg_dt <- dt[, .(value = match.fun(FUN)(value)), by = date] xts(agg_dt$value, agg_dt$date) } # 测试效果 xts_aggr_duplicates_dt(x, "mean") #> [,1] #> 2024-04-19 1.5 #> 2024-04-20 3.0 #> 2024-04-21 4.5
方法3:使用dplyr+tibble的管道风格
如果熟悉tidyverse语法,可通过管道式分组聚合后转回xts,代码可读性强,适合中小型数据集:
library(dplyr) library(tibble) xts_aggr_duplicates_tidy <- function(x, FUN) { x %>% as_tibble(rownames = "date") %>% mutate(date = as.Date(date)) %>% group_by(date) %>% summarise(value = match.fun(FUN)(value)) %>% ungroup() %>% xts(order.by = .$date) } # 测试 xts_aggr_duplicates_tidy(x, "sum") #> [,1] #> 2024-04-19 3 #> 2024-04-20 3 #> 2024-04-21 9
内容的提问来源于stack exchange,提问作者dimfalk
相关产品推荐
相关产品推荐

