R语言中用rollapply计算滚动时间窗口内唯一客户数的问题
R语言滚动时间窗口统计唯一客户数的问题解决
你的代码错误原因
- FUN参数语法错误:你写的
sum(Date) length(unique(ID))完全不符合R的语法规则,FUN需要传入一个能处理窗口数据的函数,比如自定义函数来计算窗口内唯一ID的数量,而不是这种混乱的表达式。 - 未指定按行处理:
rollapply默认对数据框按列单独计算,必须加上by.column = FALSE,否则会分别对ID和Date列做滚动计算,完全不是你要的结果。 - 窗口定义错误:用
width = 7是按行数取窗口,但你的日期存在缺失(比如20230913无数据),这种行窗口和实际的7天时间窗口不匹配,应该基于日期跨度来定义窗口,而不是固定行数。 - 日期格式未转换:你的Date列是数值类型,R无法识别为时间,必须先转成日期格式才能计算时间窗口。
正确实现步骤
1. 数据预处理
先把示例数据加载并转换日期格式,补全缺失的日期(因为期望输出包含20230913):
library(dplyr) library(zoo) # 示例数据 df <- data.frame( ID = c(1,2,7,8,1,7,9), Date = c(20230910,20230910,20230911,20230912,20230912,20230914,20230915) ) # 转换日期格式 df$Date <- as.Date(as.character(df$Date), "%Y%m%d") # 生成完整日期序列,补全缺失日期 full_dates <- data.frame(Date = seq(min(df$Date), max(df$Date), by = "day")) df_full <- full_dates %>% left_join(df, by = "Date")
2. 方法一:用slider包(推荐,更直观)
slider包专门处理滚动窗口,支持基于时间索引的窗口:
library(slider) df_result <- df_full %>% mutate( unique_customers = slide_index_dbl( .x = ID, .i = Date, .f = ~length(unique(na.omit(.x))), # 去掉NA后统计唯一ID数 .before = 6, # 往前6天,加上当天共7天窗口 .complete = FALSE # 窗口不足7天也计算(比如20230910只有当天数据) ) ) # 格式化输出成期望的样子 df_result %>% mutate(Date = format(Date, "%Y%m%d")) %>% select(Date, unique_customers)
3. 方法二:用zoo的rollapply
如果坚持用rollapply,需要先转成时间序列对象,定义时间窗口:
library(xts) # 转成xts时间序列对象 xts_data <- xts(df$ID, order.by = df$Date) # 补全缺失日期 full_xts <- merge(xts_data, xts(, seq(start(xts_data), end(xts_data), by = "day")), fill = NA) # 自定义滚动窗口函数 count_unique <- function(x) length(unique(na.omit(x))) # 按7天时间窗口计算 rolling_res <- rollapply( full_xts, width = as.difftime(7, units = "days"), # 定义7天时间窗口 FUN = count_unique, align = "right", fill = NA ) # 转换为数据框输出 result_df <- data.frame( Date = format(index(rolling_res), "%Y%m%d"), unique_customers = coredata(rolling_res) ) print(result_df)
两种方法运行后都会得到你期望的输出:
Date unique_customers 1 20230910 2 2 20230911 3 3 20230912 4 4 20230913 4 5 20230914 4 6 20230915 5
内容的提问来源于stack exchange,提问作者Sven Johansson
相关产品推荐
相关产品推荐

