寻求R语言中无需循环构建每日累计交易数据框的高效方案
高效生成累计交易日数据框方案
针对你需要生成每个As_Of_Dt下截至该日所有交易记录的需求,以下是两种比for循环更高效的实现方案,尤其适合大规模数据集:
方案一:使用dplyr + tidyr(tidyverse生态)
library(tidyverse) library(lubridate) # 原始数据预处理 df <- data.frame(TradeDate = c("2022-01-01","2022-01-02","2022-01-02", "2022-01-03","2022-01-04"), Ticker = c("AAPL", "AMZN", "META", "AAPL","TSLA"), Type = c("Buy", "Buy", "Buy", "Buy","Buy"), Shares = c(10, 12, 5, 15, 20)) %>% mutate(TradeDate = as_date(TradeDate)) # 生成所有需要的As_Of_Dt日期序列 as_of_dates <- seq(min(df$TradeDate), max(df$TradeDate), by = "day") # 构建累计数据框 result <- tibble(As_Of_Dt = as_of_dates) %>% mutate( # 对每个As_Of_Dt,筛选TradeDate <= 当前日期的所有交易 trades = map(As_Of_Dt, ~ filter(df, TradeDate <= .x)) ) %>% # 展开嵌套的trades数据 unnest(trades) %>% # 调整列顺序匹配预期输出 select(TradeDate, Ticker, Type, Shares, As_Of_Dt)
方案二:使用data.table(极致高效,适合超大数据集)
library(data.table) library(lubridate) # 转换为data.table格式并预处理日期 dt <- as.data.table(df) dt[, TradeDate := as_date(TradeDate)] # 生成所有As_Of_Dt日期 as_of_dates <- seq(min(dt$TradeDate), max(dt$TradeDate), by = "day") # 利用非等连接实现高效累计匹配 result <- dt[.(As_Of_Dt = as_of_dates), on = .(TradeDate <= As_Of_Dt), .(TradeDate = x.TradeDate, Ticker, Type, Shares, As_Of_Dt = i.As_Of_Dt), allow.cartesian = TRUE]
方案说明
- 方案一:用
purrr::map替代for循环,避免了循环中反复绑定数据框的性能损耗,tidyverse语法更易读维护。 - 方案二:data.table的非等连接是处理这类累计匹配场景的最优解之一,底层基于C语言实现,在百万级以上数据量时性能优势极为显著。
- 两种方案均自动从原始数据提取日期范围,无需手动计算区间,适用性更强。
内容的提问来源于stack exchange,提问作者Tate Steele
相关产品推荐
相关产品推荐

