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

按AT07分组计算各DT01列值为1的占比(R语言优化求助)

问题描述

我有一个包含ID、AT07以及DT01_1至DT01_19列的数据集,需要按AT07(取值为AT07_1至AT07_11)分组,统计每个DT01列中值为1的占比。之前用dplyr重复写mutate语句实现,效率极低,求高效方案。

附样本数据集:

ID   AT07 DT01_1 DT01_2 DT01_3 DT01_4 DT01_5 DT01_6 DT01_7 DT01_8 DT01_9 DT01_10 DT01_11 DT01_12 DT01_12.1
1 vD0FPVt AT07_1      1      1      1      1      1      1      1      1      1       1       1       0         0
2 UwwHYWL AT07_1      0      0      0      0      1      0      0      0      0       0       0       0         0
3 Lw7HM6J AT07_1      0      0      0      0      0      0      1      1      0       1       0       0         0
4 Llpww1k AT07_1      0      0      0      0      0      0      0      0      0       1       0       0         0
5 OwXwA9j AT07_1      0      0      0      0      0      0      1      0      0       1       1       0         0

之前的低效代码:

library(dplyr)
resLong <- resLong %>%
   group_by(AT07) %>%
   mutate(DT01_1_percent1 = label_percent()(sum(DT01_1 == 1)/n())) %>%
   mutate(DT01_2_percent1 = label_percent()(sum(DT01_2 == 1)/n())) %>%
   mutate(DT01_3_percent1 = label_percent()(sum(DT01_3 == 1)/n())) %>%
   mutate(DT01_4_percent1 = label_percent()(sum(DT01_4 == 1)/n())) %>%
   mutate(DT01_5_percent1 = label_percent()(sum(DT01_5 == 1)/n())) %>%
   mutate(DT01_6_percent1 = label_percent()(sum(DT01_6 == 1)/n())) %>%
   mutate(DT01_7_percent1 = label_percent()(sum(DT01_7 == 1)/n())) %>%
   mutate(DT01_8_percent1 = label_percent()(sum(DT01_8 == 1)/n())) %>%
   mutate(DT01_9_percent1 = label_percent()(sum(DT01_9 == 1)/n())) %>%
   mutate(DT01_10_percent1 = label_percent()(sum(DT01_10 == 1)/n())) %>%
   mutate(DT01_11_percent1 = label_percent()(sum(DT01_11 == 1)/n())) %>%
   mutate(DT01_12_percent1 = label_percent()(sum(DT01_12 == 1)/n())) %>%
   mutate(DT01_13_percent1 = label_percent()(sum(DT01_13 == 1)/n())) %>%
   mutate(DT01_14_percent1 = label_percent()(sum(DT01_14 == 1)/n())) %>%
   mutate(DT01_15_percent1 = label_percent()(sum(DT01_15 == 1)/n())) %>%
   mutate(DT01_16_percent1 = label_percent()(sum(DT01_16 == 1)/n())) %>% 
   mutate(DT01_17_percent1 = label_percent()(sum(DT01_17 == 1)/n())) %>%
   mutate(DT01_18_percent1 = label_percent()(sum(DT01_18 == 1)/n())) %>%
   mutate(DT01_19_percent1 = label_percent()(sum(DT01_19 == 1)/n()))
 
  
resLong <- resLong[,-c(1:21)]

library(dplyr)
resLong <- distinct(resLong)
高效解决方案

方法1:用dplyr的across函数(最简洁的tidyverse方式)

利用across批量处理所有DT01列,避免重复写mutate,一次完成分组计算:

library(dplyr)
library(scales) # 需加载scales包使用label_percent

res_summary <- resLong %>%
  group_by(AT07) %>%
  summarise(
    across(starts_with("DT01_"), 
           ~ label_percent()(sum(.x == 1)/n()),
           .names = "{col}_percent1")
  )

说明:

  • starts_with("DT01_")自动匹配所有DT01开头的列,覆盖DT01_1到DT01_19
  • .names = "{col}_percent1"自动生成和你之前手动命名一致的新列名
  • summarise直接输出每个分组的统计结果,不需要后续删列、去重,一步到位

方法2:转长格式处理(适配tidy数据原则,方便后续扩展)

如果之后还要对统计结果做可视化或进一步分析,转长格式会更灵活:

library(tidyr)
library(dplyr)
library(scales)

res_long_summary <- resLong %>%
  select(AT07, starts_with("DT01_")) %>% # 只保留需要的列
  pivot_longer(cols = starts_with("DT01_"), 
               names_to = "DT01_col", 
               values_to = "value") %>%
  group_by(AT07, DT01_col) %>%
  summarise(percent1 = label_percent()(sum(value == 1)/n()), .groups = "drop") %>%
  pivot_wider(names_from = DT01_col, values_from = percent1, names_glue = "{DT01_col}_percent1")

说明:

  • 先转长格式统一计算占比,再转回宽格式匹配原需求的输出结构
  • 这种方式符合tidy数据规范,后续修改统计逻辑只需改一次代码

方法3:用data.table(大数据集下效率拉满)

如果你的数据集量级很大,data.table的运算速度和内存使用会比dplyr更有优势:

library(data.table)
library(scales)

setDT(resLong) # 把数据框转成data.table格式

res_dt_summary <- resLong[, 
  lapply(.SD, function(x) label_percent()(sum(x == 1)/.N)),
  by = AT07,
  .SDcols = patterns("^DT01_")
]

# 给列名加上_percent1后缀
setnames(res_dt_summary, 
         old = patterns("^DT01_"), 
         new = paste0(names(res_dt_summary)[-1], "_percent1"))

说明:

  • .SDcols = patterns("^DT01_")指定要处理的目标列
  • .N是data.table中表示分组行数的变量,对应dplyr里的n()

内容的提问来源于stack exchange,提问作者Nadine M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:00:00