在R中动态选列计算RowMeans:基于季度循环与市场进入日期
BaseR循环实现同季度历史均值计算
思路
针对每个季度,先拆分出季度标识(如Q1)和当前年份,筛选出同季度、年份更早、且在产品市场进入日期之后的目标列(这里以Price为例,可替换为Units/Value),再逐行计算这些列的均值。完全保留原有季度循环逻辑,无需转长格式。
代码实现
# 沿用你原有的循环变量:n_qrts是季度总数,st_col_c是季度列起始索引,n_cols是每个季度的指标列数(如Units/Value/Price各1列则为3) for (i in 2:n_qrts) { # 1. 获取当前季度标识(如Q1.2024) curr_col_idx <- st_col_c - 2 + n_cols * i curr_qrt <- substr(colnames(data_c)[curr_col_idx], 1, 7) # 2. 拆分季度部分和年份 qrt_split <- strsplit(curr_qrt, "\\.")[[1]] curr_qrt_part <- qrt_split[1] # 提取Q1/Q2/Q3/Q4 curr_year <- as.integer(qrt_split[2]) # 3. 筛选所有同季度、年份更早的Price列 # 正则匹配同季度的Price列,比如Q1.2018.Price、Q1.2019.Price target_cols <- grep(paste0("^", curr_qrt_part, "\\.[0-9]{4}\\.Price$"), colnames(data_c), value = TRUE) # 只保留年份小于当前年份的列 target_cols <- target_cols[as.integer(substr(target_cols, 4, 7)) < curr_year] # 4. 结合市场进入日期,逐行计算有效历史季度的均值 data_c[, paste0(curr_qrt, "_mean")] <- apply(data_c, 1, function(row) { entry_qrt <- row["mkt_entry_date"] # 把列名转成季度标识(去掉.Price后缀),筛选出在进入市场之后的列 target_qrts <- substr(target_cols, 1, 7) valid_cols <- target_cols[target_qrts >= entry_qrt] # 没有有效列时返回NA(比如产品刚进入市场的第一个季度) if (length(valid_cols) == 0) return(NA) # 计算均值,忽略NA值 mean(as.numeric(row[valid_cols]), na.rm = TRUE) }) # 保留你原有的Price计算逻辑 data_c[, paste0(curr_qrt, ".Price")] <- data_c[, paste0(curr_qrt, ".Value")] / data_c[, paste0(curr_qrt, ".Units")] }
错误原因
你之前用pick()触发Selections can't have missing values,是因为筛选列时返回了空值或者无效索引,pick无法处理这类无效选择。用BaseR的apply逐行筛选每个产品的有效历史季度,能精准避开这个问题。
适配调整
如果你的列名规则不同(比如用下划线分隔:Q1_2018_Price),只需修改3处:
- 拆分季度时把
strsplit(curr_qrt, "\\.")改成strsplit(curr_qrt, "_") - 正则表达式改成
paste0("^", curr_qrt_part, "_[0-9]{4}_Price$") - 提取年份时把
substr(target_cols, 4, 7)替换为对应位置的截取(比如as.integer(strsplit(target_cols, "_")[[1]][2]))
内容的提问来源于stack exchange,提问作者Henrique Vasconcelos
相关产品推荐
相关产品推荐

