我已经几次发现这种问题,但我想不出一种更好(更有效)的方法。
我们有一个数据框argv[]
,其值df
按日期y
排序,并具有一个或多个类别dt
。例如,许多工具符号(“ AAPL34”,“ MSFT34”等)的股市数据。
给另一个数据帧x
,其中每行包含来自search
的某些min_dt
的日期间隔(max_dt
和category
),我想过滤{ {1}}在此类别中,并为df$x
的每一行输出时间间隔和汇总摘要量(例如均值,中位数或其他)。
我已经解决了下面的reprex中的问题,但是我觉得它非常慢(实际数据通常df
涉及10至1亿行,{{ {1}})。
search
我认为问题在于该函数为每个df
迭代创建一个副本,但是我看不出这样做的出路。任何想法表示赞赏。
答案 0 :(得分:1)
我使用data.table
重现了相同的结果,但是它实际上比OP解决方案要差。留在这里以防其他人回答:
library(data.table)
setDT(df)
setDT(search)
df[search,
on = .(dt > min_dt, dt < max_dt, x = category),
.(min_dt,max_dt,dt,x,y,category)][,list(.N, mean_val = mean(y)),
by = list(min_dt,max_dt,category)]
基准:
dt_summ = function(df,search){
setDT(df)
setDT(search)
setkeyv(df,c("dt","y"))
df[search,
on = .(dt > min_dt, dt < max_dt, x = category),
.(min_dt,max_dt,dt,x,y,category)][,
list(.N, mean_val = mean(y)),
by = list(min_dt,max_dt,category)]
}
dplyr_summ = function(df,search){
bind_cols(search, purrr::pmap_dfr(search, filter_summarise))
}
library(microbenchmark)
microbenchmark(
dplyr = dplyr_summ(df,search),
dt = dt_summ(df,search)
)
#Unit: milliseconds
# expr min lq mean median uq max neval
# dplyr 4.0562 4.4588 5.580925 4.70385 5.0531 65.5202 100
# dt 6.7754 7.5449 8.246862 7.97395 8.6485 15.8260 100