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

如何在dplyr中正确结合cut与group_by函数?

问题:group_by结合cut函数分组分箱出现异常类别数量

问题背景

尝试将cut()函数与group_by()结合,按V2和V3分组后对V1进行分箱,但生成的类别多达数十个,而非预期的3个。此前已成功用group_by()+ntile()实现分组分位数划分。

可复现代码

library(dplyr)
set.seed(1)
df <- tibble(
  V1 = round(runif(1000,min=1, max=1000)),
  V2 = round(runif(1000, min=1, max=3)),
  V3 = round(runif(1000, min=1, max=10)))

df$V2 = as.factor(df$V2)
df$V3 = as.factor(df$V3)

# 全局分箱(正常生成3个类别)
df$split= cut(df$V1, quantile(df$V1, c(0, .2, .6, 1)), include.lowest = TRUE)

# group_by+ntile正常工作
df=df %>% 
  group_by(V2,V3) %>%
  mutate(quartile_by_group = ntile(V1,4))

# group_by+cut异常,生成大量类别
df=df %>%    
  group_by(V2, V3) %>%    
  mutate(split_by_group = cut(V1, quantile(V1, c(0, .2, .6, 1)), include.lowest = TRUE))

table(df$split_by_group)

问题原因

每个分组内V1的分位数(quantile()结果)数值不同,cut()会基于这些不同的数值生成不同的区间字符串(比如组1的0.2分位数是180,组2的是220,对应区间分别为[1,180]和[1,220])。这些不同的区间在整个数据集中会被识别为独立类别,最终导致类别数量远超预期。

解决方案

通过统一分箱标签的方式,让每个分组的分箱结果映射为固定的3个类别:

方法1:用case_when自定义分箱逻辑

df <- df %>%
  group_by(V2, V3) %>%
  mutate(
    split_by_group = case_when(
      V1 <= quantile(V1, 0.2) ~ "0-20%",
      V1 <= quantile(V1, 0.6) ~ "20-60%",
      TRUE ~ "60-100%"
    ) %>% factor(levels = c("0-20%", "20-60%", "60-100%")) # 固定因子顺序
  ) %>%
  ungroup()

# 查看结果,只有3个类别
table(df$split_by_group)

方法2:保留区间但统一标签

如果需要保留原始区间信息,同时统一类别标识,可以额外生成标签列:

df <- df %>%    
  group_by(V2, V3) %>%    
  mutate(
    q_vals = list(quantile(V1, c(0, .2, .6, 1))), # 存储分组分位数
    split_by_group = cut(V1, q_vals[[1]], include.lowest = TRUE),
    split_label = factor(split_by_group, levels = split_by_group, labels = c("低区间", "中区间", "高区间"))
  ) %>%
  ungroup()

table(df$split_label)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:25:21