如何简化R语言中基于tidyverse的组内类别占比计算代码?
简化R中组内类别占比的计算方案
你这段代码功能完全没问题,但确实可以利用tidyverse的原生语法大幅简化!不用两次分组再做join,咱们可以通过更紧凑的分组聚合逻辑直接搞定组内占比计算,代码会简洁很多。
优化后的代码
library(tidyverse) # 生成示例数据 fruit <- rep(c("apples", "oranges", "bananas"), times=c(3, 2, 5)) group <- rep(c(1, 2), times=c(35, 65)) df <- data.frame(fruit, group, stringsAsFactors=FALSE) # 简洁的组内占比计算 df2 <- df %>% # 按组和水果类别计数 count(group, fruit) %>% # 仅按组重新分组,方便计算组内总和 group_by(group) %>% # 计算占比并转换为百分比 mutate(percent = n / sum(n) * 100) %>% # 选择需要的列并按组排序 select(fruit, group, percent) %>% arrange(group)
代码解释
count(group, fruit):相当于group_by(group, fruit) %>% summarise(n = n()),一步得到每个组内各类水果的数量,比手动写summarise更简洁。group_by(group):重新按组分组后,sum(n)会自动计算当前组的总数量,省去了单独统计组总数再join的步骤。- 如果需要控制百分比的小数位数,可以把
mutate里的代码改成percent = round(n / sum(n) * 100, 2),保留两位小数。
另一种等价写法
如果你习惯用summarise的方式,也可以这样写,逻辑和上面一致:
df2 <- df %>% group_by(group, fruit) %>% summarise(count = n(), .groups = "drop_last") %>% mutate(percent = count / sum(count) * 100) %>% select(fruit, group, percent) %>% arrange(group)
这里的.groups = "drop_last"会在summarise后只保留group的分组,不用再手动重新group_by。
内容的提问来源于stack exchange,提问作者Basil
相关产品推荐
相关产品推荐

