R语言实现data.frame各列取值频次统计 补全缺失计数为0的方法
核心实现方法
你遇到的问题本质是逐列统计频次时,不同列的取值覆盖范围不一致,直接用lapply(df, table)得到的列表长度、元素名无法对齐,无法直接拼成规整矩阵。只需要先定义所有列统一的取值全集,再将每列的统计结果对齐到这个全集,缺失值补0,就能快速得到目标格式,不需要逐列手动拼接。
方法1:纯基础R实现(无需额外安装包)
直接复制运行即可得到和示例完全一致的结果:
# 提取全数据集所有列的非重复取值,排序后作为统计矩阵的统一行索引 all_levels <- sort(unique(unlist(df))) # 逐列计算频次,对齐到统一行索引,缺失计数补0 res <- sapply(df, function(col) { col_tab <- table(col) # 匹配统一取值集合,无匹配的位置计数为0 count <- as.numeric(col_tab[match(all_levels, names(col_tab))]) count[is.na(count)] <- 0 setNames(count, all_levels) }) # 转换为data.frame格式 result_df <- as.data.frame(res)
运行后输出的result_df和你给出的目标格式完全匹配:
> result_df var1 var2 var3 var4 0 1 4 1 0 1 1 0 1 2 2 1 0 1 2 3 1 0 1 0
方法2:tidyverse生态实现(适配日常数据分析流程)
如果平时习惯用tidyverse语法,可以用更简洁的链式操作实现:
library(tidyverse) all_levels <- sort(unique(unlist(df))) result_df <- df |> map(\(col) { col_tab <- table(col) |> as.data.frame(stringsAsFactors = FALSE) # 右连接到统一取值集合,缺失计数补0 full_join(tibble(col_name = as.character(all_levels)), col_tab, by = c("col_name" = "Var1")) |> pull(Freq) |> replace_na(0) }) |> set_names(colnames(df)) |> as.data.frame(row.names = all_levels)
关键注意点
- 代码逻辑通用,哪怕后续数据列数增多,只要替换最初的数据集对象,就能自动完成全列统计,不需要逐列单独写
table()语句 - 自动兼容数值、字符混合的列类型,不同类型的取值会在统一匹配环节自动对齐,不需要单独手动转格式
- 对于极端偏态的列(比如某列只有一个固定取值),也会自动在其他取值的行位补0,不会出现维度错位
内容的提问来源于stack exchange,提问作者JORIS
相关产品推荐
相关产品推荐

