计算数据框各列字符值占比:测试数据集代码报错的解决需求
计算数据框各列字符值的列内占比问题
问题背景
给定测试数据框:
df <- data.frame( w1 = c("A","A","B","C","A"), w2 = c("C","A","A","C","C"), w3 = c("C","A","B","C","B") )
需要计算每列中各字符值的列内占比,但使用以下代码在测试数据集报错(该代码在包含所有字符类别的大数据集中可正常运行):
df %>% summarise(across(everything(), ~prop.table(table(.))*100))
期望得到包含字符值标识列、缺失类别占比补0的结果,格式如下:
字符值 w1 w2 w3 1 A 60 40 20 2 B 20 0 40 3 C 20 60 40
报错原因
测试数据集的部分列缺失部分字符类别(比如w2列没有B),prop.table(table(.))仅统计当前列存在的类别,导致各列返回的结果长度不一致,summarise无法将这些长度不同的结果组合成数据框,因此触发报错。而大数据集可能每列都包含所有字符类别,所以不会出现此问题。
解决方案
方法1:统一全局类别后计算占比
先提取所有列的唯一字符值作为全局类别,再对每列按该类别统计频数并计算占比:
library(dplyr) library(tidyr) # 获取所有列的唯一字符值,作为统一统计的类别 all_levels <- unique(unlist(df)) df %>% summarise(across(everything(), ~{ # 将当前列转为因子,指定全局类别,缺失类别自动补0 tab <- table(factor(., levels = all_levels)) prop.table(tab) * 100 })) %>% # 转置结果并整理格式 t() %>% as.data.frame() %>% rownames_to_column(var = "字符值") %>% rename_with(~colnames(df), -1) %>% arrange(字符值)
方法2:通过数据重塑计算占比
先将数据转为长格式,统计各列各字符的频数,计算占比后再转回宽格式:
library(dplyr) library(tidyr) df %>% # 转为长格式:列名、字符值 pivot_longer(everything(), names_to = "列名", values_to = "字符值") %>% # 统计每列每个字符的出现次数 count(列名, 字符值) %>% # 按列分组计算占比 group_by(列名) %>% mutate(占比 = n / sum(n) * 100) %>% select(-n) %>% # 转回宽格式,缺失类别补0 pivot_wider(names_from = 列名, values_from = 占比, values_fill = 0) %>% arrange(字符值)
两种方法均能生成符合要求的结果,自动为缺失类别的列填充0。
内容的提问来源于stack exchange,提问作者Chris Ruehlemann
相关产品推荐
相关产品推荐

