ggplot箱线图添加观测权重的实现方法求助
问题:绘制考虑观测权重的地区工资加权箱线图
需求:基于包含观测权重pesofit的数据集,绘制按地区(nome_reg)划分的工资(tpens)加权箱线图,但在ggplot的aes中添加weight=pesofit后出现警告,无法实现加权效果。
数据集样例
> head(final2, 20) nquest nord ireg staciv etalav acontrib nome_reg tpens pesofit 1 173 1 18 3 25 35 Calabria 1800 0.3801668 2 2886 1 13 1 26 35 Abruzzo 1211 0.2383701 3 2886 2 13 1 20 42 Abruzzo 2100 0.2383701 4 5416 1 8 3 16 30 Emilia Romagna 700 0.8819879 5 7886 1 9 1 22 35 Toscana 2000 1.2452078 6 20297 1 5 1 14 39 Veneto 1200 1.6694498 7 20711 2 4 1 15 37 Trentino 2000 3.3746801 8 22169 1 15 4 40 5 Campania 600 1.6875562 9 22276 1 8 2 18 37 Emilia Romagna 1200 2.1782894 10 22286 1 8 1 15 19 Emilia Romagna 850 3.0333999 11 22286 2 8 1 15 35 Emilia Romagna 650 3.0333999 12 22657 1 16 1 25 40 Puglie 1400 0.3616937 13 22657 2 16 1 26 36 Puglie 1500 0.3616937 14 23490 1 5 2 23 36 Veneto 1400 0.9763965 15 24147 1 4 1 26 35 Trentino 1730 1.2479984 16 24147 2 4 1 18 45 Trentino 1600 1.2479984 17 24853 1 11 1 18 38 Marche 2180 0.3475683 18 27238 1 12 1 16 31 Lazio 1050 3.6358952 19 27730 1 20 1 15 37 Sardegna 1470 0.7232677 20 27734 1 20 1 16 45 Sardegna 1159 0.6959107
变量说明
nquest:家庭编码nord:家庭成员编码nome_reg:居住地区tpens:个人工资pesofit:观测权重
原普通箱线图代码(可正常运行)
final2 %>% filter(nome_reg == "Piemonte"| nome_reg == "Valle D'Aosta" | nome_reg == "Lombardia" | nome_reg == "Liguria" ) %>% ggplot(aes( x = factor(nome_reg, levels=c("Piemonte", "Valle D'Aosta", "Lombardia", "Liguria")), y = tpens , fill = nome_reg ))+ geom_boxplot(varwidth = TRUE)
尝试加权后的代码及警告
尝试添加weight=pesofit后代码:
final2 %>% filter(nome_reg == "Piemonte"| nome_reg == "Valle D'Aosta" | nome_reg == "Lombardia" | nome_reg == "Liguria") %>% ggplot(aes( x = factor(nome_reg, levels=c("Piemonte", "Valle D'Aosta", "Lombardia", "Liguria")), y = tpens , fill = nome_reg, weight = pesofit ))+ geom_boxplot(varwidth = TRUE)
返回警告:
Warning message: The following aesthetics were dropped during statistical transformation: weight i This can happen when ggplot fails to infer the correct grouping structure in the data. i Did you forget to specify a `group` aesthetic or to convert a numerical variable into a factor?
解决方案
核心原因:ggplot2默认的stat_boxplot不支持weight美学参数,无法直接通过添加weight实现加权箱线图,需要手动计算加权分位数或使用支持加权的扩展包。
方法一:手动计算加权分位数后绘图
使用Hmisc包的wtd.quantile函数计算各组的加权分位数,再用ggplot绘制箱线图:
- 先安装并加载所需包:
install.packages("Hmisc") library(dplyr) library(ggplot2) library(Hmisc)
- 过滤数据并计算加权统计量:
weighted_box_data <- final2 %>% filter(nome_reg %in% c("Piemonte", "Valle D'Aosta", "Lombardia", "Liguria")) %>% mutate(nome_reg = factor(nome_reg, levels = c("Piemonte", "Valle D'Aosta", "Lombardia", "Liguria"))) %>% group_by(nome_reg) %>% summarize( # 计算加权分位数 ymin = wtd.quantile(tpens, weights = pesofit, probs = 0), lower = wtd.quantile(tpens, weights = pesofit, probs = 0.25), middle = wtd.quantile(tpens, weights = pesofit, probs = 0.5), upper = wtd.quantile(tpens, weights = pesofit, probs = 0.75), ymax = wtd.quantile(tpens, weights = pesofit, probs = 1), # 计算加权样本量(用于varwidth) n = sum(pesofit) )
- 绘制加权箱线图:
ggplot(weighted_box_data, aes(x = nome_reg, fill = nome_reg)) + geom_boxplot( aes(ymin = ymin, lower = lower, middle = middle, upper = upper, ymax = ymax), stat = "identity", varwidth = TRUE ) + labs(y = "tpens")
方法二:使用ggstatsplot包直接绘制加权箱线图
ggstatsplot包的ggboxplot函数原生支持weight参数,无需手动计算:
- 安装并加载包:
install.packages("ggstatsplot") library(ggstatsplot) library(dplyr)
- 绘制加权箱线图:
final2 %>% filter(nome_reg %in% c("Piemonte", "Valle D'Aosta", "Lombardia", "Liguria")) %>% mutate(nome_reg = factor(nome_reg, levels = c("Piemonte", "Valle D'Aosta", "Lombardia", "Liguria"))) %>% ggboxplot( x = "nome_reg", y = "tpens", fill = "nome_reg", weight = "pesofit", varwidth = TRUE )
内容的提问来源于stack exchange,提问作者io_boh
相关产品推荐
相关产品推荐

