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

R语言:如何自动按等距区间批量分组汇总数值列?

问题描述

现有数据:

(df <- data.frame(
  random_str = rep("ok", 30),
  value      = rnorm(30, mean=50, sd=25)
))

可通过以下代码按random_str分组计算基本统计量:

df %>% 
  group_by(random_str) %>% 
  summarise(max = max(value),
            min = min(value)
            # 其他统计量...
  )

但还需将value列按指定区间(如0-33、34-66、67-100)分组统计数量,手动实现方式如下:

df %>% 
  group_by(random_str) %>% 
  summarise(max = max(value),
            min = min(value),
            # 其他统计量...
            count1_33  = sum(value < 34),
            count34_66  = sum(value < 67 & value > 33),
            count67_100 = sum(value > 66)
  )

实际场景中有百万行数据,且需设置上百个等距区间,求自动实现这类分组统计的方法。


解决方案

方法1:cut()+count()+pivot_wider()(简洁高效,推荐)

先通过cut()将数值批量分箱,再分组计数后转宽格式,最后和基本统计量合并,完全避免手动编写区间条件:

library(dplyr)
library(tidyr)

# 定义等距区间:示例为0-100、步长33,上百个区间直接用seq生成即可
breaks <- seq(0, 100, by = 33)
# 给区间设置清晰的列名标签
labels <- paste0(breaks[-length(breaks)], "-", breaks[-1])

# 生成区间计数(宽格式)
bin_counts <- df %>%
  mutate(value_bin = cut(value, breaks = breaks, labels = labels, include.lowest = TRUE)) %>%
  group_by(random_str, value_bin) %>%
  count(name = "count") %>%
  pivot_wider(names_from = value_bin, values_from = count, values_fill = 0)

# 计算基本统计量
basic_stats <- df %>%
  group_by(random_str) %>%
  summarise(max = max(value), min = min(value))

# 合并最终结果
final_result <- basic_stats %>% left_join(bin_counts, by = "random_str")

该方法基于向量化操作,处理百万行数据效率远高于手动写多个sum()条件。

方法2:利用hist()批量生成区间计数

针对严格等距区间,可直接用hist()的统计结果快速生成所有区间计数,无需额外分箱步骤:

library(dplyr)

# 定义区间参数
start <- 0
end <- 100
bin_width <- 33
breaks <- seq(start, end, by = bin_width)

# 一次性计算基本统计量+所有区间计数
final_result <- df %>%
  group_by(random_str) %>%
  summarise(
    max = max(value),
    min = min(value),
    # 用!!!将命名列表展开为列,自动生成区间计数列
    !!!set_names(
      map(value, ~ hist(., breaks = breaks, plot = FALSE)$counts),
      paste0("count_", breaks[-length(breaks)], "_", breaks[-1])
    )
  )

方法3:data.table优化大数据性能

如果数据量达到百万级,data.table的分组操作速度和内存效率更突出:

library(data.table)

setDT(df)
breaks <- seq(0, 100, by = 33)
labels <- paste0(breaks[-length(breaks)], "-", breaks[-1])

# 分箱计数并转宽格式
bin_counts_wide <- df[, .(count = .N), by = .(random_str, value_bin = cut(value, breaks = breaks, labels = labels, include.lowest = TRUE))] %>%
  dcast(random_str ~ value_bin, value.var = "count", fill = 0)

# 计算基本统计量
basic_stats <- df[, .(max = max(value), min = min(value)), by = random_str]

# 合并结果
final_result <- merge(basic_stats, bin_counts_wide, by = "random_str")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:02:37