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

如何用tidy方式结合summarise函数计算两类分组相关中位数

问题描述

现有数据集如下:

idtypevalue
x1A1
x1A2
x1A3
x1B2
x1B4
x1B6
x1C1
x1C3
x1C5

需要生成两类汇总列:

  • 每个type分组对应的value的中位数;
  • 排除当前type后,其余所有type的value的中位数(例如type-A对应type-B和C的value中位数)

期望输出结果:

idtypemedian_type_valuemedian_non_type_value
x1A23.5
x1B42.5
x1C32.5

目前已实现第一类汇总的代码,但无法完成第二类汇总:

library(tidyverse)
df = data.frame(id=c(rep("x1",9)), type=c(rep("A",3),rep("B",3),rep("C",3)), value=c(1,2,3,2,4,6,1,3,5))

df %>% 
group_by(id,type) %>% 
summarise(median_type_value=median(value))
解决方案

可以通过先按id分组保存全量数据,再针对每个type筛选排除自身的数据集计算中位数,具体代码如下:

library(tidyverse)
df = data.frame(id=c(rep("x1",9)), type=c(rep("A",3),rep("B",3),rep("C",3)), value=c(1,2,3,2,4,6,1,3,5))

df %>%
  # 按id分组,将当前id下的所有type和value打包为列表列
  group_by(id) %>%
  mutate(all_data = list(tibble(type, value))) %>%
  # 在id分组基础上新增type分组
  group_by(id, type, .add = TRUE) %>%
  summarise(
    # 计算当前type分组内的中位数
    median_type_value = median(value),
    # 筛选排除当前type的value并计算中位数
    median_non_type_value = median(filter(first(all_data), type != cur_group()$type)$value),
    .groups = "drop"
  )

代码说明

  1. group_by(id) + mutate(all_data = list(tibble(type, value))):把当前id下的所有数据打包成列表,方便后续跨分组调用;
  2. group_by(id, type, .add = TRUE):保留原有id分组的同时,新增type分组维度;
  3. median_type_value = median(value):和原有代码逻辑一致,计算当前type分组内的中位数;
  4. median_non_type_value = median(filter(first(all_data), type != cur_group()$type)$value):从全量数据中过滤掉当前type的行,提取剩余value计算中位数,cur_group()$type用于获取当前分组的type标识。

运行上述代码即可得到符合预期的输出结果。

内容的提问来源于stack exchange,提问作者deman23

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 16:37:14