如何在R中绘制半柯西、马蹄、拉普拉斯、正态分布并得到指定对比效果
问题描述
需要在R中绘制半柯西(Half Cauchy)、马蹄(Horseshoe)、拉普拉斯(Laplace)、正态(Normal)四种随机变量的分布对比图,原有代码运行结果不符合预期,原有代码如下:
compare_priors <- function(scale = 1, df_t = 2, xlim = c(-6, 6),ylim=c(0,50)) { dt_loc_scale <- function(x, df, location, scale) { 1/scale * dt((x - location)/scale, df) } dlaplace <- function(x, location, scale) { 0.5 / scale * exp(-abs(x - location) / scale) } dhos<-function (x, location, scale, log = FALSE){ dens <- dnorm(x, 0, location * 25, log = log) } stat_dist <- function(dist, ...) { ggplot2::stat_function(ggplot2::aes_(color = dist), ...) } ggplot2::ggplot(data.frame(x = xlim), ggplot2::aes(x)) + stat_dist("normal", size = 0.8, fun = dnorm, args = list(mean = 0, sd = scale)) + stat_dist("student_t", size = 0.8, fun = dt_loc_scale, args = list(df = df_t, location = 0, scale = scale)) + stat_dist("cauchy", size = 0.8, linetype = 2, fun = dcauchy, args = list(location = 0, scale = scale)) + stat_dist("laplace", size = 0.8, linetype = 2, fun = dlaplace, args = list(location = 0, scale = scale))+ stat_dist("horseshoe", size = 0.8, linetype = 2, fun = dhos, args = list(location = 0, scale = scale)) } # Cauchy has fattest tails, followed by student_t, laplace, and normal compare_priors()
代码问题梳理
- 缺失半柯西分布的实现,原有代码仅绘制了全区间的柯西分布,半柯西仅在x≥0时有值,密度为全柯西的2倍
- 马蹄分布的密度函数实现错误,原代码错误调用了正态分布的密度函数
- 绘图区间设置错误,目标为正半轴的半分布对比,x轴应从0开始,不需要负半轴区间
- 冗余绘制了学生t分布,目标对比图中无该分布
- 半拉普拉斯、半正态的密度未做对应调整,半分布的密度需要在x≥0时乘以2,x<0时为0
修正后实现代码
compare_priors <- function(scale = 1, xlim = c(0, 6), ylim=c(0, 1.2)) { # 半正态分布密度 dhalfnorm <- function(x, sd) { ifelse(x < 0, 0, 2 * dnorm(x, mean = 0, sd = sd)) } # 半拉普拉斯分布密度 dhalflaplace <- function(x, location = 0, scale) { ifelse(x < 0, 0, 2 * 0.5 / scale * exp(-abs(x - location) / scale)) } # 半柯西分布密度 dhalfcauchy <- function(x, location = 0, scale) { ifelse(x < 0, 0, 2 * dcauchy(x, location = location, scale = scale)) } # 马蹄分布密度(标准参数化) dhorseshoe <- function(x, scale = 1) { ifelse(x == 0, 1/(pi * scale), ifelse(x < 0, 0, (1/(pi * scale)) * log(1 + 2*(scale^2)/(x^2)))) } # 封装绘图层 stat_dist <- function(dist, ...) { ggplot2::stat_function(ggplot2::aes(color = dist), linewidth = 0.8, ...) } ggplot2::ggplot(data.frame(x = xlim), ggplot2::aes(x)) + stat_dist("半正态", fun = dhalfnorm, args = list(sd = scale)) + stat_dist("半拉普拉斯", fun = dhalflaplace, args = list(scale = scale)) + stat_dist("半柯西", fun = dhalfcauchy, args = list(scale = scale), linetype = 2) + stat_dist("马蹄", fun = dhorseshoe, args = list(scale = scale), linetype = 2) + ggplot2::ylim(ylim) + ggplot2::labs(color = "分布类型", x = "x", y = "密度") + ggplot2::theme_bw() } # 调用函数绘图 compare_priors()
效果说明
运行修正后的代码即可得到符合预期的四种半分布对比图,各分布的尾部厚重程度符合半柯西>马蹄>半拉普拉斯>半正态的特征。
内容的提问来源于stack exchange,提问作者Francesco De Vincentis
相关产品推荐
相关产品推荐

