R语言按组自定义Bin Range:基于组内Max-Min划分5个分箱
按组自定义分箱并映射回原数据框的解决方案
要实现每个组基于自身Sales的极值动态生成5个等距分箱,核心思路是在分组后计算每组专属的分箱断点,再用cut()函数将原始Sales值映射到对应区间。以下是具体实现步骤:
1. 准备示例数据
先把你提供的数据集转为可操作的tibble:
library(tidyverse) df <- tibble( Date = c("Jan-17", "Feb-17", "Mar-17", "Apr-17", "May-17", "Jan-17", "Feb-17", "Mar-17", "Apr-17", "May-17"), Group = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B"), Sales = c(1000, 1200, 700, 2000, 1800, 5000, 5800, 6800, 7000, 6000) )
2. 核心代码实现
这里我们用group_by()分组后,动态计算每组的分箱断点,再完成映射:
df_with_bins <- df %>% group_by(Group) %>% mutate( # 生成6个断点(对应5个区间):从组内Sales最小值到最大值等距分布 breaks = list(seq(min(Sales), max(Sales), length.out = 6)), # 将Sales值映射到对应分箱区间,include.lowest确保最小值被包含在第一个区间 freq = cut(Sales, breaks = unlist(breaks), include.lowest = TRUE) ) %>% # 移除中间生成的breaks列,保持数据整洁 select(-breaks) %>% ungroup()
3. 代码解释
group_by(Group):确保所有计算都是基于单个组的Sales数据,避免跨组干扰seq(min(Sales), max(Sales), length.out = 6):生成6个等距断点,刚好划分出5个区间(比如A组断点为700, 980, 1260, 1540, 1820, 2000)list()包装断点序列:解决分组后每个组的断点长度一致但需要存为列的问题cut(..., include.lowest = TRUE):保证每组的最小值不会被排除在第一个区间外
4. 输出结果示例
运行代码后,你会得到带分箱区间的数据框:
print(df_with_bins) # # A tibble: 10 × 3 # Date Group Sales freq # <chr> <chr> <dbl> <fct> # 1 Jan-17 A 1000 [700,980] # 2 Feb-17 A 1200 (980,1260] # 3 Mar-17 A 700 [700,980] # 4 Apr-17 A 2000 (1820,2000] # 5 May-17 A 1800 (1540,1820] # 6 Jan-17 B 5000 [5000,5400] # 7 Feb-17 B 5800 (5400,5800] # 8 Mar-17 B 6800 (6600,7000] # 9 Apr-17 B 7000 (6600,7000] # 10 May-17 B 6000 (5800,6200]
可选优化:自定义区间格式
如果你想让区间显示更符合习惯(比如统一用[a,b]格式),可以给cut()加上dig.lab参数控制数字位数,或者用factor()重新调整标签:
df_with_bins <- df %>% group_by(Group) %>% mutate( breaks = list(seq(min(Sales), max(Sales), length.out = 6)), freq = cut(Sales, breaks = unlist(breaks), include.lowest = TRUE, dig.lab = 4) ) %>% select(-breaks) %>% ungroup()
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

