ggplot2的stat_function()无法精确绘制t分布尾部曲线下面积
解决t分布尾部填充未延伸至临界线的问题
你猜的没错!问题确实出在stat_function默认生成的x采样点刚好没包含你的临界值l.critical,导致填充区域在接近临界线时就因为NA中断了,没法完全贴合垂直线。下面给你两种可靠的解决思路:
方法1:强制在x采样序列中包含临界值
你可以手动构造包含临界值的x向量,直接用geom_area绘制填充区域,精准控制所有需要的点:
alpha=0.1 n=5 l.critical = qt(alpha,df=n-1) u.critical = -l.critical # 构造包含临界值的x序列:先取范围,再插入临界值 x_range <- seq(l.critical-3, u.critical+3, length.out = 200) x_full <- unique(c(x_range, l.critical)) # 加入临界值并去重 x_full <- sort(x_full) # 排序保证顺序 # 计算t分布的y值,以及填充区域的y值 t_dist <- data.frame( x = x_full, y = dt(x_full, df = n-1), y_shaded = ifelse(x_full <= l.critical, dt(x_full, df = n-1), NA) ) ggplot(t_dist, aes(x = x)) + geom_line(aes(y = y), linewidth=1) + # 绘制t分布曲线 geom_area(aes(y = y_shaded), fill="#84CA72", alpha=1, color="black") + # 填充尾部 scale_x_continuous(name = "t values")+ theme(axis.text.y = element_blank(), axis.ticks.y = element_blank())+ labs(y="")+ geom_vline(xintercept=l.critical)
方法2:给stat_function增加采样点数并传递临界值
如果你还是想用stat_function,可以通过n参数增加采样点数量(降低错过临界值的概率),同时把临界值作为参数传入填充函数:
alpha=0.1 n=5 l.critical = qt(alpha,df=n-1) u.critical = -l.critical # 修改填充函数,接收临界值作为参数 funcShaded <- function(x, crit) { y <- dt(x,df=n-1) y[x>crit]<-NA return(y) } ggplot(data.frame(x = c(l.critical-3,u.critical+3)), aes(x = x)) + stat_function(fun = dt, args = list(df=n-1), linewidth=1)+ scale_x_continuous(name = "t values")+ stat_function(fun=funcShaded, args = list(crit = l.critical), geom="area", fill="#84CA72", alpha=1, outline.type="full",color="black", n = 1000) + # 大幅增加采样点数量 theme(axis.text.y = element_blank(), axis.ticks.y = element_blank())+ labs(y="")+ geom_vline(xintercept=l.critical)
为什么之前的代码在部分自由度下失效?
stat_function默认只生成101个采样点,当l.critical的数值刚好不在这些采样点中时,y[x>l.critical]<-NA会把临界线左侧最近的采样点设为NA,导致填充区域提前终止,看起来就没贴合垂直线。而像自由度4(n=5)时刚好采样点命中了临界值,所以显示正常。
通过手动加入临界值或者大幅增加采样点数量,就能避免这个问题,让填充区域完美延伸到临界线。
内容的提问来源于stack exchange,提问作者mutinda festus
相关产品推荐
相关产品推荐

