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

基于R语言按性别分体重区间的多维度数据汇总验证

验证并修正R语言体重区间划分代码

问题背景

现有包含体重、哮喘情况(1=患有哮喘,0=未患哮喘)、性别及id的数据集,生成代码如下:

library(dplyr)
library(purrr)
library(ggplot2)
set.seed(123)

my_data1 = data.frame(Weight =  rnorm(500,100,100), asthma = sample(c(0,1), prob = c(0.7,0.3), replace=TRUE, size= 500))
my_data2 = data.frame(Weight = rnorm(500, 200, 50),  asthma = sample(c(0,1), prob = c(0.3,0.7), replace=TRUE, size= 500))
my_data_a = rbind(my_data1, my_data2)
my_data_a$gender =  "male"

my_data1 = data.frame(Weight =  rnorm(500,100,100), asthma = sample(c(0,1), prob = c(0.7,0.3), replace=TRUE, size= 500))
my_data2 = data.frame(Weight = rnorm(500, 200, 50),  asthma = sample(c(0,1), prob = c(0.3,0.7), replace=TRUE, size= 500))
my_data_b = rbind(my_data1, my_data2)
my_data_b$gender =  "female"

my_data = rbind(my_data_a, my_data_b)
my_data$id = 1:2000

需求为:针对男女两种性别,将人群按体重升序划分为固定宽度30单位的区间(例如男性最小体重至最小体重+30为男性第1区间,以此类推),并统计每个区间的人数、区间内最小体重和最大体重。

用户尝试的代码如下:

Part_1 = my_data %>% group_by(gender) %>%
    mutate(bins = cut(Weight , breaks = pretty(Weight , n = (max(Weight)-min(Weight))/30), include.lowest = TRUE)) %>% 
 mutate(rank = dense_rank(bins)) %>% 
mutate(new_bins = paste(rank,"_", gender, sep=""))

Part_2 = Part_1 %>% group_by(gender, bins) %>% 
    summarize(min_weight = min(Weight), max_weight = max(Weight), count = n())

Part_3 = merge(x=Part_1,y=Part_2, by.x=c("gender","bins"), by.y=c("gender","bins"))

原代码的问题

原代码的核心问题在于使用pretty()函数生成区间断点:

  • pretty()的设计目标是生成“美观”的数值断点(比如整十、整百),不会严格遵循从组内最小体重开始、固定宽度30的要求。从用户给出的示例输出可以看到,女性的区间是(-100,-50],宽度为50,明显不符合30的固定宽度需求。
  • 额外的merge步骤可以简化,无需拆分再合并,直接在分组流程中完成统计更高效。

修正后的代码

以下代码严格按照需求实现固定宽度区间划分,并简化了流程:

library(dplyr)

# 按性别分组,生成固定宽度30的体重区间并统计
final_result <- my_data %>%
  group_by(gender) %>%
  mutate(
    # 获取当前性别体重的最小、最大值
    group_min = min(Weight),
    group_max = max(Weight),
    # 生成断点序列:从组内最小体重向下取整开始,步长30,直到覆盖最大体重
    break_points = list(seq(from = floor(group_min), 
                           to = ceiling(group_max) + 30, 
                           by = 30)),
    # 划分区间,include.lowest确保最小值被包含在第一个区间
    bins = cut(Weight, breaks = unlist(break_points), include.lowest = TRUE)
  ) %>%
  # 按性别和区间分组,统计所需指标
  group_by(gender, bins) %>%
  mutate(
    min_weight = min(Weight),
    max_weight = max(Weight),
    count = n(),
    # 生成区间的升序排名
    rank = dense_rank(bins),
    new_bins = paste(rank, "_", gender, sep = "")
  ) %>%
  # 清理临时变量,整理输出列顺序
  ungroup() %>%
  select(gender, bins, Weight, asthma, id, rank, new_bins, min_weight, max_weight, count)

验证说明

  • 区间划分逻辑:每个性别内部的断点从该组体重最小值向下取整开始,每次递增30,确保每个区间的宽度严格为30单位。
  • 统计指标:min_weight和max_weight是对应区间内实际的体重极值,count为区间内的人数,完全匹配需求。
  • 流程简化:无需拆分数据再合并,通过一次分组流转完成所有操作,代码更简洁高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:05:24