You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:30:20