R语言实现带QQ line的facet wrap分面QQ plot绘制方法
R语言绘制带真实QQ线的分面QQ图
原有实现中使用geom_smooth(method = "lm")得到的是全组线性拟合线,和基础R中qqline()的真实QQ线定义不一致。真实QQ线的计算逻辑为:取样本25%、75%分位数,匹配对应正态理论的25%、75%分位数计算斜率与截距,穿过这两个点的直线即为标准QQ参考线。
完整实现代码
1. 加载依赖包
library(ggplot2) library(dplyr)
2. 构造示例数据
set.seed(123) df1 <- data.frame(vals = rnorm(1000, 10), y = sample(LETTERS[1:3], 1000, replace = TRUE), z = sample(letters[1:3], 1000, replace = TRUE))
3. 分组计算理论分位数与QQ线参数
按分面维度分组,为每个分组单独计算QQ线的斜率和截距,保证和base::qqline输出完全一致:
df_q <- df1 %>% group_by(y, z) %>% mutate( # 正态理论分位数 xq = qqnorm(vals, plot = FALSE)$x, # 计算QQ线参数 q25 = quantile(vals, 0.25), q75 = quantile(vals, 0.75), norm25 = qnorm(0.25), norm75 = qnorm(0.75), slope = (q75 - q25) / (norm75 - norm25), intercept = q25 - slope * norm25 ) %>% ungroup()
4. 绘制分面QQ图
(1)facet_grid 版本
ggplot(df_q, aes(x = xq, y = vals)) + geom_point(size = 0.8, alpha = 0.7) + # 映射分组计算得到的截距和斜率,生成真实QQ线 geom_abline(aes(intercept = intercept, slope = slope), color = "red", linewidth = 0.8) + labs(x = "理论分位数", y = "样本分位数") + facet_grid(y ~ z) + theme_bw()
(2)facet_wrap 版本
ggplot(df_q, aes(x = xq, y = vals)) + geom_point(size = 0.8, alpha = 0.7) + geom_abline(aes(intercept = intercept, slope = slope), color = "red", linewidth = 0.8) + labs(x = "理论分位数", y = "样本分位数") + # 可自由调整分面排布规则 facet_wrap(~ y + z, nrow = 3) + theme_bw()
如果你习惯使用plyr做分组计算,仅需将第3步的分组逻辑替换为ddply写法即可,核心是每个分面分组单独计算QQ线参数,再通过geom_abline映射即可。
内容的提问来源于stack exchange,提问作者Nicki_NZ
相关产品推荐
相关产品推荐

