按分组统计多列中不同值(含NA)的出现次数
用tidyverse实现分组统计各变量值及NA的出现次数
实现代码
library(tidyverse) # 原始数据 df <- data.frame (Gr = c("A","A","A","B","B","B","B","B","B"), Var1 = c("a","b","c","e","a","a","c","e","b"), Var2 = c("a","a","a","d","b","b","c","a","e"), Var3 = c("e","a","b",NA,"a","b","c","d","a"), Var4 = c("e",NA,"a","e","a","b","d","c",NA)) # 核心处理流程 result <- df %>% # 宽表转长表,统一变量列格式 pivot_longer(cols = starts_with("Var"), names_to = "Vars", values_to = "Value") %>% # 按分组、变量、值分组(强制保留所有组合),统计次数 group_by(Gr, Vars, Value, .drop = FALSE) %>% summarise(count = n(), .groups = "drop") %>% # 长表转宽表,缺失计数填充为0 pivot_wider(names_from = Value, values_from = count, values_fill = 0) %>% # 整理NA列,确保a-e列无缺失值 mutate( na = `NA`, across(c(a, b, c, d, e), ~ replace_na(., 0)) ) %>% # 调整列顺序 select(Vars, a, b, c, d, e, na) %>% # 按分组拆分为命名列表 group_split(Gr, .keep = FALSE) %>% set_names(unique(df$Gr))
代码说明
pivot_longer:将Var1到Var4的宽格式列转换为长格式,把变量名存入Vars列,对应值存入Value列,便于统一统计。group_by(..., .drop = FALSE):关闭自动丢弃空分组的功能,确保每个变量的所有目标类别(a-e、NA)都被统计,避免后续缺失列。pivot_wider:将统计后的长格式数据转回宽格式,用values_fill = 0填充未出现类别的计数。mutate段:将NA对应的列重命名为na,并用replace_na确保a-e列的缺失值填充为0。group_split + set_names:按Gr分组拆分数据框,同时给列表元素命名为对应的分组名(A、B)。
验证结果
运行代码后打印result,输出结构与需求完全一致:
> print(result) $A # A tibble: 4 × 7 Vars a b c d e na <chr> <int> <int> <int> <int> <int> <int> 1 Var1 1 1 1 0 0 0 2 Var2 3 0 0 0 0 0 3 Var3 1 1 0 0 1 0 4 Var4 1 0 0 0 1 1 $B # A tibble: 4 × 7 Vars a b c d e na <chr> <int> <int> <int> <int> <int> <int> 1 Var1 2 1 1 0 2 0 2 Var2 1 2 1 1 1 0 3 Var3 2 1 1 1 0 1 4 Var4 1 1 1 1 1 1
内容的提问来源于stack exchange,提问作者sm1231
相关产品推荐
相关产品推荐

