如何在R时间序列数据中统计每期产品的新增门店数量?
统计产品每期新增门店数的R实现方案
需求说明
现有包含门店级销售数据的R数据框df,数据按产品-门店-周期组合构成时间序列,需统计每个产品每期的新增门店数量,要求每个产品的第1周期新增门店数默认设为0。数据包含核心字段:store_id(门店ID)、prod_id(产品ID)、period(周期)、sales(销售额)。
样本数据
prod_id period store_id sales 12345 1 0001 6 12345 1 0002 8 12345 2 0003 10 12345 2 0004 4 54321 1 0001 5 54321 1 0005 9 54321 2 0001 11 54321 2 0005 7
理想输出
prod_id period new_stores 12345 1 0 12345 2 2 54321 1 0 54321 2 0
原代码问题分析
你尝试的代码逻辑存在核心错误:使用lag(store_id)仅能获取当前行的上一行门店ID,而非该产品此前所有周期的全部门店集合,导致!store_id %in% Prev_Store_Codes的判断完全失效,无法正确识别新增门店。原代码如下:
new_stores_per_period <- df %>% arrange(prod_id, period) %>% group_by(prod_id) %>% mutate(Prev_Store_Codes = lag(store_id, default = "")) %>% mutate(New_Store = !store_id %in% Prev_Store_Codes) %>% group_by(prod_id, period) %>% summarize(No_Of_New_Stores = sum(New_Store))
修正方案
方案一:基于首次出现周期统计
核心思路是先记录每个产品-门店的首次销售周期,再统计当期等于首次周期的门店数量,最后将第1周期数值置为0:
library(dplyr) # 1. 获取每个产品-门店的首次销售周期 first_appearance <- df %>% group_by(prod_id, store_id) %>% summarize(first_period = min(period), .groups = "drop") # 2. 统计每期新增门店数并处理第1周期 new_stores_per_period <- df %>% distinct(prod_id, period) %>% # 保留所有产品-周期组合 left_join(first_appearance, by = "prod_id") %>% group_by(prod_id, period) %>% summarize(new_stores = sum(first_period == period, na.rm = TRUE), .groups = "drop") %>% mutate(new_stores = ifelse(period == 1, 0, new_stores)) %>% arrange(prod_id, period)
方案二:基于累积门店集合统计
通过累积此前所有周期的门店集合,计算当期门店与累积集合的差集大小得到新增数:
library(dplyr) library(purrr) new_stores_per_period <- df %>% arrange(prod_id, period) %>% group_by(prod_id) %>% # 按周期收集当期所有门店 group_by(period, .add = TRUE) %>% summarize(stores = list(unique(store_id)), .groups = "drop_last") %>% # 生成截止到当期之前的累积门店集合 mutate(prev_stores = accumulate(stores, ~ union(.x, .y), .init = list()) %>% head(-1)) %>% # 计算差集长度即新增门店数 mutate(new_stores = map2_int(stores, prev_stores, ~ length(setdiff(.x, .y)))) %>% # 第1周期置为0 mutate(new_stores = ifelse(period == 1, 0, new_stores)) %>% select(prod_id, period, new_stores)
内容的提问来源于stack exchange,提问作者Rnovice
相关产品推荐
相关产品推荐

