如何按MemID行统计指定因子变量中各因子水平的出现次数?
问题:按成员ID统计多变量中各因子水平的出现次数
需求:按行(每个MemID)统计特定因子水平在多个指定变量中的出现次数,示例中仅针对value_a和value_b两个变量统计各成员选择不同因子水平的次数。
示例数据
results=data.frame(MemID=c('A','B','C','D','E','F','G','H'), value_a = c(1,2,1,4,5,1,4,0), value_b = c(1,5,2,3,4,1,0,3), value_c = c(3,5,2,1,1,1,2,1) )
期望输出
counts_by_level = data.frame(MemID=c('A','B','C','D','E','F','G','H'), count_1 = c(2, 0, 1, 0, 0, 2, 0, 0), count_2 = c(0, 1, 1, 0, 0, 0, 0, 0), count_3 = c(0, 0, 0, 1, 0, 0, 0, 1), count_4 = c(0, 0, 0, 1, 1, 0, 1, 0), count_5 = c(0, 1, 0, 0, 1, 0, 0, 0))
解决方案
方法1:使用tidyverse包(dplyr + tidyr)
通过数据重塑、分组统计再转回宽格式实现:
library(tidyverse) counts_by_level <- results %>% # 筛选需要统计的列 select(MemID, value_a, value_b) %>% # 宽表转长表,合并目标变量 pivot_longer(cols = -MemID, names_to = "variable", values_to = "level") %>% # 过滤不需要的0值(若需统计0可删除此行) filter(level != 0) %>% # 按成员ID和因子水平分组计数 count(MemID, level, name = "count") %>% # 长表转宽表,补全缺失水平的计数为0 pivot_wider(names_from = level, values_from = count, names_prefix = "count_", values_fill = 0) %>% # 确保所有目标水平列存在 complete(MemID, fill = list(count_1=0, count_2=0, count_3=0, count_4=0, count_5=0)) %>% # 匹配原数据的成员ID顺序 arrange(factor(MemID, levels = results$MemID))
方法2:使用Base R
通过行遍历和表格统计实现:
# 指定需要统计的变量和因子水平 target_cols <- c("value_a", "value_b") target_levels <- 1:5 # 按成员ID拆分数据并逐个统计 counts_list <- lapply(split(results[, c("MemID", target_cols)], results$MemID), function(x) { # 合并当前成员的目标变量值 vals <- unlist(x[, target_cols]) # 统计各水平次数,补全缺失水平为0 tab <- table(factor(vals, levels = target_levels)) # 整理为数据框并添加成员ID data.frame(MemID = x$MemID[1], as.list(tab)) }) # 合并结果并重命名列,匹配原顺序 counts_by_level <- do.call(rbind, counts_list) colnames(counts_by_level)[-1] <- paste0("count_", target_levels) counts_by_level <- counts_by_level[match(results$MemID, counts_by_level$MemID), ]
内容的提问来源于stack exchange,提问作者Jordan J
相关产品推荐
相关产品推荐

