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

如何用purrr将分组分位数优雅转为数据框多列?

解决分组分位数转多列的问题

嘿,我懂你现在的困扰——把分组计算出来的分位数列表展开成单独的列,确实是用purrr时很常见的小卡点。我给你几个优雅的解决方案,总有一款适合你:

方法1:用unnest_wider()直接拆分列表列

这是最贴合你现有代码的方式,在你已经写好的nest+map代码后面,加上unnest_wider()就能把列表列里的向量直接拆成多列,还能自定义列名:

library(tidyverse)

n <- 1000
toydata <- data.frame(
  sex = as.character(ifelse(rnorm(n)>0, "M", "F")),
  value = rnorm(n)
)
p <- c(.1, .25, .5, .75, .9)

# 给分位数设置清晰的列名,再拆分
toydata %>% 
  group_by(sex) %>% 
  nest() %>% 
  mutate(
    # 先给每个分位数命名为q10、q25这种格式
    quantiles = map(data, ~set_names(quantile(.$value, p, na.rm=TRUE), 
                                   str_c("q", p*100)))
  ) %>%
  # 把列表列拆成多列
  unnest_wider(quantiles) %>%
  # 不需要原始数据列的话可以删掉
  select(-data)

运行后你会得到一个整洁的 tibble,每行对应一个性别,五列分别是q10到q90的分位数。

方法2:直接在map里返回tibble

如果你想一步到位生成可直接展开的结构,可以在map函数里直接返回一个tibble,这样后续用unnest()就能轻松展开:

toydata %>% 
  group_by(sex) %>% 
  nest() %>% 
  mutate(
    quantiles = map(data, ~tibble(
      q10 = quantile(.$value, 0.1, na.rm=TRUE),
      q25 = quantile(.$value, 0.25, na.rm=TRUE),
      q50 = quantile(.$value, 0.5, na.rm=TRUE),
      q75 = quantile(.$value, 0.75, na.rm=TRUE),
      q90 = quantile(.$value, 0.9, na.rm=TRUE)
    ))
  ) %>%
  unnest(quantiles) %>%
  select(-data)

这种方法的好处是列名完全由你掌控,但如果分位数数量多的话会有点重复代码。

方法3:不用nest/map,直接用dplyr的summarize+across

如果你不需要保留原始分组数据的嵌套结构,这是最简洁的方法——直接用across函数对每个分位数概率批量计算:

toydata %>% 
  group_by(sex) %>% 
  summarize(
    # 对p里的每个概率计算分位数,自动生成q10、q25这样的列名
    across(all_of(p), ~quantile(value, .x, na.rm=TRUE), .names = "q{.x*100}")
  )

一行代码搞定分组+计算+多列生成,完全不需要嵌套操作,非常高效!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:46:47