如何在R中按分组计算两个月的数据集乘积并分列展示
问题描述
我有两个数据集:
- groups数据集:包含分组字段
idgroup和系数列coef,示例数据如下:
groups=structure(list(idgroup = c(1L, 3L, 4L), coef = c(2.1, 1.7, 1.3)), class = "data.frame", row.names = c(NA, -3L))
- perc数据集:包含
idgroup、百分比列percent和月份字段month_id,示例数据如下:
perc = structure(list(idgroup = c(1L, 2L, 4L, 5L), percent = c(0.4753, 0.5392, 0.48, 0.51), month_id = c(202304L, 202304L, 202305L, 202305L)), class = "data.frame", row.names = c(NA, -4L))
需要实现:将两个数据集中匹配的idgroup对应的coef与percent相乘,按month_id分别计算,把每个月份的结果放在单独列中(最多两个月),最终输出格式如下:
idgroup month_id1 month_id2 1 1 0.99813 NA 2 4 NA 0.624
其中month_id1对应第一个月份(如202304),month_id2对应第二个月份(如202305)。
解决方案
可以通过数据合并、计算乘积、重塑宽格式三步实现,以下提供两种常用方法:
方法一:基础R实现
# 1. 合并数据集,仅保留groups中存在的idgroup merged_data <- merge(groups, perc, by = "idgroup", all.x = TRUE) # 2. 计算系数与百分比的乘积 merged_data$result <- merged_data$coef * merged_data$percent # 3. 提取并排序唯一月份,生成对应列名 unique_months <- sort(unique(merged_data$month_id[!is.na(merged_data$month_id)])) col_names <- paste0("month_id", seq_along(unique_months)) # 4. 将长格式数据转为宽格式 result_wide <- reshape(merged_data, idvar = "idgroup", timevar = "month_id", v.names = "result", direction = "wide") # 5. 重命名列并过滤全NA的行 colnames(result_wide)[-1] <- col_names result_wide <- result_wide[!apply(result_wide[, -1], 1, function(x) all(is.na(x))), ] rownames(result_wide) <- NULL # 输出结果 print(result_wide)
方法二:tidyverse工具包实现
如果习惯使用dplyr和tidyr,代码更简洁直观:
library(dplyr) library(tidyr) result_wide <- groups %>% inner_join(perc, by = "idgroup") %>% # 仅保留两个数据集共有的idgroup mutate(result = coef * percent) %>% # 计算乘积 arrange(month_id) %>% # 按月份排序,确保month_id1对应最早月份 mutate(month_col = paste0("month_id", dense_rank(month_id))) %>% # 生成月份列名 pivot_wider(id_cols = idgroup, names_from = month_col, values_from = result) %>% # 转为宽格式 filter(!if_all(-idgroup, is.na)) # 移除所有结果为NA的行 # 输出结果 print(result_wide)
内容的提问来源于stack exchange,提问作者psysky
相关产品推荐
相关产品推荐

