R语言如何计算分组列相对份额 固定组总和并补全缺失组合为0
dplyr 实现分组固定总值计算+缺失组合补全方案
核心解决逻辑
- 要实现同
twodigit组indtotal取值恒定,计算行业总就业时不要把smb加入分组维度,用mutate()而非summarize()生成列:mutate不会折叠分组行,同组所有行会被赋予相同的汇总值,避免总就业被smb维度拆分。 - 要补全每个行业下缺失的smb分类,用
tidyr::complete()显式声明需要覆盖的维度组合,不存在的组合直接填0即可。
完整可运行代码
library(dplyr) library(tidyr) # 测试数据构造 naicstest <- c (512131,512141,521921,522654,512131,536978,541214,531214,621112,541213,551212,574121,569887,541211,523141,551122,512312,521114,522112) employment <- c(11,130,315,17,190,21,22,231,15,121,19,21,350,110,515,165,12,110,111) smb <- c(1,2,3,1,3,1,1,3,1,2,1,1,4,2,4,3,1,2,2) first <- data.frame(naicstest,employment,smb) %>% mutate(twodigit = substr(naicstest,1,2)) # 指标计算 result <- first %>% # 按两位数行业编码分组,计算行业总就业,同组所有行indtotal一致 group_by(twodigit) %>% mutate(indtotal = sum(employment)) %>% # 按行业+smb规模分组,计算各规模组就业总和 group_by(twodigit, smb, indtotal) %>% summarise(smbtotal = sum(employment), .groups = "drop") %>% # 补全所有行业下smb=1到4的组合,缺失的smbtotal填0 complete(twodigit, smb = 1:4, fill = list(smbtotal = 0)) %>% # 补全新增行的indtotal值(同行业值固定) group_by(twodigit) %>% fill(indtotal, .direction = "downup") %>% # 计算小企业占比,调整列顺序 mutate(smbshare = smbtotal / indtotal) %>% select(twodigit, indtotal, smb, smbtotal, smbshare)
关键步骤说明
- 之前的错误写法是把
smb和twodigit同时作为分组变量做summarize,汇总粒度直接到了行业+规模组,自然拿不到行业层面的固定总值。 complete()执行时会生成所有传入维度的笛卡尔积,传入smb=1:4就会强制每个twodigit组都覆盖smb的4个取值,不需要手动遍历补行。- 补全操作会让新增行的
indtotal暂时为缺失值,按twodigit分组做上下填充即可把同组的行业总值同步到所有新增行,最后直接做除法就能得到正确的占比结果。
内容的提问来源于stack exchange,提问作者Tim Wilcox
相关产品推荐
相关产品推荐

