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

R语言:按分组批量统计多列中'yes'的占比

按分组统计多列中"yes"的占比(tidyverse高效实现)

需求说明

按group列分组,统计数据框中其余每一列里"yes"出现的占比(忽略NA值,结果保留两位小数),示例数据及期望结果如下:

示例数据:

df <- data.frame(group = c("a","a","a","a","b","b","b","b"),
                 female = c("yes","no","yes","no","yes","yes","yes","no"),
                 alcohol = c("yes","no",NA,"no","yes","yes","no","no"))

期望结果:

> df_result
  group female alcohol
1     a   0.50    0.33
2     b   0.75    0.50

解决方案

使用tidyverse中的dplyr包,通过group_by()+summarise()+across()组合实现,无需逐一指定列名:

library(tidyverse)

# 示例数据
df <- data.frame(group = c("a","a","a","a","b","b","b","b"),
                 female = c("yes","no","yes","no","yes","yes","yes","no"),
                 alcohol = c("yes","no",NA,"no","yes","yes","no","no"))

# 核心代码
df_result <- df %>%
  group_by(group) %>%
  # 对所有非分组列计算yes的占比,忽略NA
  summarise(across(everything(), ~ mean(.x == "yes", na.rm = TRUE))) %>%
  ungroup() %>%
  # 保留两位小数,匹配示例格式
  mutate(across(-group, ~ round(.x, 2)))

# 查看结果
df_result

代码解释

  • group_by(group):按group列进行分组
  • across(everything(), ~ mean(.x == "yes", na.rm = TRUE)):
    • across(everything()):自动遍历除分组列外的所有列,无需手动列名
    • .x == "yes":将列中每个元素转为逻辑值(等于"yes"为TRUE,否则FALSE)
    • mean(..., na.rm = TRUE):逻辑值的均值即为TRUE的占比,na.rm = TRUE忽略NA值(和示例中a组alcohol的计算逻辑一致:3个非NA值里1个yes,占比1/3≈0.33)
  • ungroup():取消分组状态,避免后续操作受分组影响
  • mutate(across(-group, ~ round(.x, 2))):对除group外的列保留两位小数,匹配期望结果格式

扩展说明

如果只想统计特定类型的列(比如仅字符型列),可以把across(everything())改成:

across(where(is.character), ~ mean(.x == "yes", na.rm = TRUE))

如果需要排除某几列,比如排除group和另一列xxx,可以用:

across(-c(group, xxx), ~ mean(.x == "yes", na.rm = TRUE))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 11:27:32