如何复刻ggpubr中的QQ图?含回归线与标准误差区域实现
复刻ggpubr的QQ图:修正理论分位数与添加QQ线、置信区间
你目前的代码核心问题是理论分位数计算错误,ggpubr的ggqqplot()并非用标准化的秩作为理论分位数,而是基于正态分布的理论分位点计算。以下是修正方案:
一、修正理论分位数计算
正确的理论分位数需要基于样本的分位点(加入连续修正避免极端值),用qnorm()生成正态分布的对应分位数:
library(tidyverse) library(ggpubr) # 准备数据 x <- iris$Petal.Length n <- length(x) # 计算修正后的分位点与理论分位数 df <- tibble( sample_quantiles = sort(x), rank = rank(x), p = (rank - 0.5)/n, # 连续修正的分位点,避免0或1 theoretical_quantiles = qnorm(p) )
二、绘制正确的QQ线
QQ图的回归线本质是基于样本均值和标准差的拟合:y = 样本均值 + 样本标准差 × 理论分位数。你可以直接用这个公式绘制,或者用lm()拟合,结果完全相同:
# 计算样本统计量 mu <- mean(x) sigma <- sd(x) # ggplot绘制 df %>% ggplot(aes(x = theoretical_quantiles, y = sample_quantiles)) + geom_point(size = 1.5) + # 添加QQ线:两种方式二选一 geom_abline(intercept = mu, slope = sigma, color = "black", linewidth = 0.5) + # 或者用lm拟合:geom_smooth(method = "lm", se = FALSE, color = "black", linewidth = 0.5) + theme_pubr() + labs(x = "理论分位数", y = "样本分位数", title = "正态QQ图")
三、添加标准误差(置信区间)区域
ggpubr的QQ图置信区间通常基于bootstrap抽样实现,以下是手动实现的方法:
# Bootstrap生成置信区间 set.seed(123) # 固定种子保证可重复 boot_samples <- replicate(1000, { boot_x <- sample(x, size = n, replace = TRUE) sort(boot_x) }) # 计算每个样本分位数的95%置信区间 ci_low <- apply(boot_samples, 1, quantile, 0.025) ci_high <- apply(boot_samples, 1, quantile, 0.975) # 合并到数据框 df <- df %>% mutate(ci_low = ci_low, ci_high = ci_high) # 重新绘制带置信区间的QQ图 df %>% ggplot(aes(x = theoretical_quantiles, y = sample_quantiles)) + geom_ribbon(aes(ymin = ci_low, ymax = ci_high), alpha = 0.2, fill = "gray") + geom_point(size = 1.5) + geom_abline(intercept = mu, slope = sigma, color = "black", linewidth = 0.5) + theme_pubr() + labs(x = "理论分位数", y = "样本分位数", title = "带95%置信区间的正态QQ图")
关键说明
- 之前的
scale(rank)得到的是标准化的秩,并非正态分布的理论分位数,这是导致图与ggqqplot()差异的核心原因。 - QQ线的本质是将正态分布的理论分位数通过样本的均值和标准差映射到样本的尺度,用
geom_abline直接指定截距和斜率比geom_smooth更直接。 - Bootstrap置信区间通过重复抽样模拟样本分位数的分布,能准确复刻ggpubr中置信区域的效果。
内容的提问来源于stack exchange,提问作者Shawn Hemelstrand
相关产品推荐
相关产品推荐

