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

R语言:如何新增合并指定行的记录且保留原数据(tidyverse优先)

问题

我有一份包含不同社会经济地位(SES)个体的纵向数据集,原始数据将SES划分为High、Mid、Mid Low、Low四类。我想要新增一行聚合Mid Low和Low两类的统计数据,同时保留原有的4类数据。目前我能通过代码获取聚合信息,但结果是以列的形式呈现,不知道怎么优雅地转成行数据。

数据集示例

library(dplyr)

test_data <- tibble(month = c(rep(c("Jan"), 4), rep(c("Feb"), 4)),
                    ses = c(rep(c("High", "Mid", "Mid Low", "Low"), 2)),
                    total = c(10, 20, 20, 30, 9, 11, 40, 60),
                    total_selected = c(9, 10, 8, 3, 8, 6, 8, 6)) %>%
  group_by(month, ses) %>%
  mutate(success_rate = total_selected/total)

当前代码(结果为列形式)

(test_data2 <- test_data %>%
  group_by(month) %>%
  mutate(three_ses_total = case_when(
    ses %in% c("High", "Mid") ~ total,
    ses %in% c("Mid Low", "Low") ~ (total[ses == "Mid Low"] + total[ses == "Low"])
  ),
  three_ses_total_selected = case_when(
    ses %in% c("High", "Mid") ~ total_selected,
    ses %in% c("Mid Low", "Low") ~ (total_selected[ses == "Mid Low"] + total_selected[ses == "Low"])
  ),
  three_ses_success_rate = case_when(
    ses %in% c("High", "Mid") ~ success_rate,
    ses %in% c("Mid Low", "Low") ~ three_ses_total_selected/three_ses_total
  )))

期望输出

(answer <- tibble(month = c(rep(c("Jan"), 5), rep(c("Feb"), 5)),
                    ses = c(rep(c("High", "Mid", "Mid Low", "Low", "Mid Low and Low"), 2)),
                    total = c(10, 20, 20, 30, 50, 9, 11, 40, 60, 100),
                    total_selected = c(9, 10, 8, 3, 11, 8, 6, 8, 6, 14)) %>%
  group_by(month, ses) %>%
  mutate(success_rate = total_selected/total))

希望用dplyr、tidyr等tidyverse工具优雅解决。

解决方案

可以通过先聚合目标分组,再将聚合结果与原数据合并的方式实现,逻辑清晰且符合tidyverse风格:

  1. 从原数据中筛选出需要聚合的Mid Low和Low两类,按month分组计算合并后的统计值,指定新的ses类别名称;
  2. 将聚合得到的行数据与原数据集合并;
  3. 可选:按month和ses排序,让结果结构更规整。

完整代码如下:

library(dplyr)

# 生成聚合数据
aggregated_data <- test_data %>%
  filter(ses %in% c("Mid Low", "Low")) %>%
  group_by(month) %>%
  summarise(
    ses = "Mid Low and Low",
    total = sum(total),
    total_selected = sum(total_selected),
    success_rate = total_selected / total,
    .groups = "drop"
  )

# 合并原数据与聚合数据,按需排序
final_data <- test_data %>%
  bind_rows(aggregated_data) %>%
  arrange(month, ses)

# 查看结果
final_data

代码解释

  • filter(ses %in% c("Mid Low", "Low")):筛选出需要聚合的两类数据;
  • group_by(month) %>% summarise(...):按月份分组,计算合并后的total、total_selected和success_rate,并设置新的ses标签;
  • bind_rows(aggregated_data):将聚合得到的行追加到原数据末尾;
  • arrange(month, ses):按月份和SES类别排序,让结果与期望输出结构一致。

这种方式避免了原代码生成冗余列的问题,直接生成目标行数据,符合tidyverse"每行对应一个观测"的原则。

内容的提问来源于stack exchange,提问作者J.Sabree

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:36:22