如何遍历DataFrame统计频次并生成9×9计数DataFrame?
如何将30行9列的DataFrame转换为9×9的计数矩阵(统计1-9的出现次数)
问题描述
我有一个30行9列的DataFrame,所有元素都是1-9的整数。需要统计每一列中每个数字(1到9)的出现次数,最终生成一个9行9列的计数DataFrame——行对应1-9的数字,列对应原DataFrame的列,若某数字在原列中未出现则填充0。
尝试过for循环、tapply、自定义函数,但无法在循环中将结果存入新的DataFrame。以下是尝试的代码:
for (i in seq_along(columnHeaderQuosureList)) { original_data_frame %>% group_by(!! columnHeaderQuosureList[[i]]) %>% # Unquote with !! count(!! columnHeaderQuosureList[[i]]) %>% print() }
这段代码能打印每列的计数,但将print()替换为return()后,尝试用cbind合并到结果DataFrame时无法成功,需要更优解决方案。
解决方案
方法1:使用tidyverse工具链(dplyr + tidyr + purrr)
通过批量处理每一列,补全1-9的所有值并填充缺失计数为0,最终合并为目标DataFrame:
library(dplyr) library(tidyr) library(purrr) # 定义需要统计的完整数字范围 all_numbers <- 1:9 # 遍历原DataFrame的每一列,生成对应计数向量 count_list <- map(original_data_frame, function(col) { tibble(num = col) %>% count(num) %>% # 补全1-9中未出现的数字,计数填充为0 complete(num = all_numbers, fill = list(n = 0)) %>% # 提取纯计数列 pull(n) }) # 将列表转换为9×9的DataFrame,设置行名为1-9 result_df <- as.data.frame(count_list) rownames(result_df) <- all_numbers
方法2:使用Base R实现(无需额外包)
利用table函数统计次数,再补全缺失数字的计数:
all_numbers <- 1:9 # 处理每一列,生成包含完整1-9计数的向量 result_list <- lapply(original_data_frame, function(col) { col_table <- table(col) # 对每个数字检查是否在table中,存在则取对应计数,否则填0 sapply(all_numbers, function(x) { ifelse(as.character(x) %in% names(col_table), col_table[as.character(x)], 0) }) }) # 转换为DataFrame并设置行名 result_df <- as.data.frame(result_list) rownames(result_df) <- all_numbers
说明
- 两种方法的核心逻辑一致:先统计列内现有数字的次数,再补全1-9中缺失数字的计数为0,确保每列都有9个对应值。
- 方法1适合熟悉tidyverse管道操作的用户,代码可读性更强;方法2依赖Base R,无需加载第三方包,轻量高效。
- 最终生成的
result_df即为9行9列的计数矩阵,完全符合需求。
内容的提问来源于stack exchange,提问作者wiltabone
相关产品推荐
相关产品推荐

