R语言:按ACCOUNT和CashInd计算4天内聚合计数(优化循环)
嘿,我太懂你用for循环处理这种滚动计数的痛苦了——数据量一大,那速度慢得让人抓狂!咱们直接换高效的方法,别再跟循环死磕啦。下面给你两种比apply还快的实现方案,都是业界常用的高效工具:
方案1:用data.table实现极速滚动计数
data.table是处理大数据集的神器,底层是C++实现,速度甩循环几条街。步骤很简单:
library(data.table) library(lubridate) # 用来处理日期时间间隔 # 先把数据框转成data.table格式 setDT(dataAlog) # 务必先按分组键和时间排序,保证窗口计算的顺序正确 dataAlog <- dataAlog[order(CashInd, ACCOUNT, DateTime)] # 按CashInd和ACCOUNT分组,计算当前记录往前4天内的累计计数 dataAlog[, rolling_count := frollsum( x = Cnt, n = Inf, # 自适应窗口大小 align = "right", # 窗口以当前行为终点 adaptive = TRUE, window = DateTime >= (DateTime - days(4)) # 定义窗口:时间在当前时间前4天到当前之间 ), by = .(CashInd, ACCOUNT)]
因为你的Cnt全是1,所以求和的结果就是符合条件的记录数,完美匹配你的需求。
方案2:用dplyr + slider实现(更贴合tidyverse风格)
如果你平时习惯用tidyverse的语法,slider包专门用来处理滑动窗口,代码可读性拉满:
library(dplyr) library(slider) library(lubridate) dataAlog <- dataAlog %>% # 先按分组和时间排序,这一步必不可少 arrange(CashInd, ACCOUNT, DateTime) %>% # 按CashInd和ACCOUNT分组 group_by(CashInd, ACCOUNT) %>% # 计算滚动窗口内的计数 mutate(rolling_count = slide_index_dbl( x = Cnt, i = DateTime, # 用DateTime作为窗口的索引 .f = sum, # 对窗口内的Cnt求和(因为Cnt=1,就是计数) .before = days(4), # 窗口范围是当前时间往前4天 .complete = FALSE # 即使窗口不满4天也计算,比如组内前几条记录 )) %>% ungroup()
关键注意事项
- 一定要确保
DateTime是日期时间类型(比如POSIXct或Date),如果不是,先用ymd_hms()或as.Date()转换。 - 两种方法都完美覆盖了你原循环的逻辑:同一
CashInd+ACCOUNT分组内,时间≤当前记录且在过去4天内的所有记录数。 - 这两种方法的速度都远胜for循环和apply系列函数,尤其是当你的数据有几万甚至几十万行时,差距会特别明显。
内容的提问来源于stack exchange,提问作者useR
相关产品推荐
相关产品推荐

