R遍历dataframe计算时间序列距离 实现营销活动试控门店配对
问题原因
- 维度报错核心原因:函数内循环第一行覆盖了传入的
trial参数,原本trial是试验门店编号,第一次运行后被覆盖为试验门店的销售额数据框,第二次循环执行filter(store_nbr == trial)时无法匹配到任何门店,得到的空数据框计算相关性时触发维度不匹配错误。 - 结果存储报错原因:对数据框赋值的语法错误,未加引号的
Control_nbr、Correlation会被识别为变量而非列名,且逐行追加的写法会反复重构数据框,效率极低。
修正方案
高效写法(避免循环扩容)
直接用向量化操作完成计算,无需显式循环,代码更简洁效率更高:
# 加载需要的包 library(dplyr) library(purrr) my.fun <- function(trial_store) { # 先提取一次试验门店的销售额数据,不要放到循环里重复计算 trial_sales <- stores_stats_pre %>% filter(store_nbr == trial_store) %>% pull(total_sales) # 向量化遍历所有对照门店计算相关系数 cor_res <- map_dbl(st.vector, function(control_store) { control_sales <- stores_stats_pre %>% filter(store_nbr == control_store) %>% pull(total_sales) cor(control_sales, trial_sales) }) # 直接生成结果数据框返回 data.frame( Trial_nbr = trial_store, Control_nbr = st.vector, Correlation = cor_res ) } # 调用示例:计算单个试验门店的对照相关性 res_77 <- my.fun(77) # 按相关性从高到低排序取前5个对照门店 top_controls <- res_77 %>% arrange(desc(Correlation)) %>% head(5) # 批量计算所有3家试验门店的结果,直接合并即可 all_res <- map_dfr(trial_stores, my.fun)
循环写法(提前初始化避免扩容)
如果习惯用循环逻辑,提前初始化固定长度的向量存结果即可:
my.fun <- function(trial_store) { trial_sales <- stores_stats_pre %>% filter(store_nbr == trial_store) %>% pull(total_sales) # 提前初始化向量,长度和对照门店数量一致 cor_vec <- numeric(length(st.vector)) for (i in seq_along(st.vector)) { control_store <- st.vector[i] control_sales <- stores_stats_pre %>% filter(store_nbr == control_store) %>% pull(total_sales) cor_vec[i] <- cor(control_sales, trial_sales) } data.frame( Trial_nbr = trial_store, Control_nbr = st.vector, Correlation = cor_vec ) }
额外校验项
如果修正后依然报维度错误,可先校验所有门店的历史数据是否完整:
# 校验所有门店的历史数据行数是否都是7 store_count <- stores_stats_pre %>% count(store_nbr) any(store_count$n !=7)
如果返回TRUE就是有门店数据不全,过滤掉这些门店再计算即可。
内容的提问来源于stack exchange,提问作者JWill
相关产品推荐
相关产品推荐

