R中对身高年龄分等频组后计算自行车拥有率,代码是否正确?
代码问题分析与修正
你的代码分组逻辑不符合需求,但后续计算占比的部分是正确的。
核心问题:分组方式错误
你要求将height和age分成等大小的组(每组人数大致相同),但当前使用的cut(x, breaks=5)是把变量的数值范围平分为5段,而非按样本数量的分位数分组。这种分组方式会导致每组的人数差异较大,无法满足“各组人数大致相同”的要求。
正确的分组方法
要实现等大小分组,有两种常用方案:
- 方案1:用
dplyr::ntile()直接生成1-5的组编号,简单高效; - 方案2:用
cut()结合quantile()生成带具体数值范围的分组标签,更贴合你想要的“年龄30-35岁”这类直观表述。
修正后的完整代码
这里采用方案2,保留分组范围的可读性:
library(dplyr) set.seed(123) n <- 100 country <- sample(c("USA", "Canada", "UK"), n, replace = TRUE) gender <- sample(c("M", "F"), n, replace = TRUE) age <- sample(18:100, n, replace = TRUE) height <- runif(n, min = 150, max = 180) owns_bicycle <- sample(c("Yes", "No"), n, replace = TRUE) df <- data.frame(country, gender, age, height, owns_bicycle) # 修正分组逻辑:按分位数生成等大小组 final <- df %>% mutate( # 按身高的分位数分成5组,include.lowest=TRUE确保最小值被包含 height_group = cut(height, breaks = quantile(height, probs = seq(0, 1, 0.2)), include.lowest = TRUE), # 按年龄的分位数分成5组 age_group = cut(age, breaks = quantile(age, probs = seq(0, 1, 0.2)), include.lowest = TRUE) ) %>% group_by(country, gender, height_group, age_group) %>% summarise( count = n(), percent_own_bicycle = mean(owns_bicycle == "Yes") * 100, .groups = "drop" # 取消分组,避免输出残留分组信息 ) # 查看结果 head(final)
修正后的输出示例
# A tibble: 6 x 6 country gender height_group age_group count percent_own_bicycle <chr> <chr> <fct> <fct> <int> <dbl> 1 Canada F [150.1,156.3] [18,31] 3 33.3 2 Canada F [150.1,156.3] (31,47] 2 0 3 Canada F [150.1,156.3] (63,80] 1 100 4 Canada F (156.3,162.4] [18,31] 1 0 5 Canada F (156.3,162.4] (31,47] 2 0 6 Canada F (156.3,162.4] (47,63] 1 0
验证分组大小
你可以通过以下代码查看每个分组的人数,确认是否大致相同:
# 查看身高分组的人数分布 df %>% mutate(height_group = ntile(height, 5)) %>% count(height_group) # 查看年龄分组的人数分布 df %>% mutate(age_group = ntile(age, 5)) %>% count(age_group)
输出会显示每个组的人数基本为20左右(总样本100,5组每组约20),符合你“各组人数大致相同”的要求。
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

