【发布时间】:2019-12-27 17:54:24
【问题描述】:
我已经多次发现这种问题,但我无法找到更好(更有效)的方法。
我们有一个数据框df,其值y按日期排序dt和一个或多个类别x。例如,许多工具代码的股票市场数据(“AAPL34”、“MSFT34”等)。
给定另一个数据框search,每行包含来自df$x 的某些category 的日期间隔(min_dt 和max_dt),我想在此类别和间隔和输出摘要中过滤df search 的每一行的数量(如平均值、中位数或其他)。
我已经解决了下面的问题,但我觉得它非常很慢(实际数据通常涉及 df 的 10-1 亿行和 search 的数千行)。
library(dplyr)
library(lubridate)
df <- tibble(dt = seq(ymd("2019-01-01"), ymd("2019-12-26"), by = "day"),
x = rep(letters[1:3], 120),
y = rnorm(360))
search <- tibble(category = c("a", "a", "b", "c"),
min_dt = ymd(c("2019-02-02", "2019-06-06", "2019-08-08", "2019-12-12")),
max_dt = ymd(c("2019-04-04", "2019-07-07", "2019-11-11", "2019-12-30")))
# My current solution
filter_summarise <- function(category, min_dt, max_dt) {
df %>%
filter(x == category, dt > min_dt, dt < max_dt) %>%
summarise(n = n(), mean_val = mean(y))
}
bind_cols(search, purrr::pmap_dfr(search, filter_summarise))
# A tibble: 4 x 5
category min_dt max_dt n mean_val
<chr> <date> <date> <int> <dbl>
1 a 2019-02-02 2019-04-04 20 0.0618
2 a 2019-06-06 2019-07-07 10 0.170
3 b 2019-08-08 2019-11-11 32 -0.127
4 c 2019-12-12 2019-12-30 5 -0.345
我认为问题在于该函数会为每个purrr::map 迭代创建一个副本,但我看不到这样做的出路。任何想法都值得赞赏。
【问题讨论】:
-
另外,使用
dt > min_dt意味着与最小日期相同的日期不会包含在内;这是故意的吗?如果不是,应该是>= -
@camille 感谢您的回复。我不习惯
data.table,但也许这个问题需要它。我会看看这些问题。至于您的第二条评论,我仅在此示例中使用>,尽管是的,使用>=更有意义。