【问题标题】:How to plot regression transformed back on original scale with colored confidence interval bands?如何用彩色置信区间带绘制回归原始比例的图?
【发布时间】:2020-06-29 07:57:52
【问题描述】:

我想从线性模型中绘制直线和 95% 置信区间,其中响应已被 logit 转换回原始数据规模。所以结果应该是一条曲线,包括原始尺度上的置信区间,而它在 logit 转换尺度上是一条直线。见代码:

# Data
dat <- data.frame(c(45,75,14,45,45,55,65,15,3,85),
                  c(.37, .45, .24, .16, .46, .89, .16, .24, .23, .49))
colnames(dat) <- c("age", "bil.")               


# Logit transformation
dat$bb_logit <- log(dat$bil./(1-dat$bil.))

# Model
modelbb <- lm(bb_logit ~ age + I(age^2), data=dat)
summary(modelbb)

# Backtranform
dat$bb_back <- exp(predict.lm(modelbb))/ (1 + exp(predict.lm(modelbb)))

# Plot
plot(dat$age, dat$bb_back)
abline(modelbb)

我在这里尝试的是绘制曲线回归线并添加置信区间。在ggplot2 中有geom_smooth 函数可以指定线性模型,但我找不到从predict.lm(my model) 绘制预测的方法。

我还想知道如何添加表示置信区间的彩色多边形,如下图所示。我知道我必须使用函数polygon 和坐标,但我不知道如何。

【问题讨论】:

    标签: r plot regression transformation confidence-interval


    【解决方案1】:

    您可以在年龄范围内使用predict,例如1:100,为CI 指定interval= 选项。使用type="l" 绘图将平滑一条漂亮的曲线。然后可以使用lines 添加置信区间。

    p <- predict(modelbb, data.frame(age=1:100), interval="confidence")
    # Backtransform
    p.tr <- exp(p) / (1 + exp(p))
    
    plot(1:100, p.tr[,1], type="l", ylim=range(p.tr), xlab="age", ylab="bil.")
    sapply(2:3, function(i) lines(1:100, p.tr[,i], lty=2))
    legend("topleft", legend=c("fit", "95%-CI"), lty=1:2)
    

    产量


    编辑

    要获得阴影置信带,请使用polygon。由于您需要两个置信度级别,您可能需要为每个置信度级别设置一个 prediction。该行将被polygons 覆盖,因此最好先使用type="n" 制作一个空的plot,然后在最后绘制lines。 (请注意,我还将向您展示一些自定义轴标签的提示。)polygons 的技巧是使用 rev 来回表达值。

    p.95 <- predict(modelbb, data.frame(age=1:100), interval="confidence", level=.95)
    p.99 <- predict(modelbb, data.frame(age=1:100), interval="confidence", level=.99)
    # Backtransform
    p.95.tr <- exp(p.95) / (1 + exp(p.95))
    p.99.tr <- exp(p.99) / (1 + exp(p.99))
    
    plot(1:100, p.99.tr[,1], type="n", ylim=range(p.99.tr), xlab="Age", ylab="",
         main="", yaxt="n")
    mtext("Tree biomass production", 3, .5)
    mtext("a", 2, 2, at=1.17, xpd=TRUE, las=2, cex=3)
    axis(2, (1:5)*.2, labels=FALSE)
    mtext((1:5)*2, 2, 1, at=(1:5)*.2, las=2)
    mtext(bquote(Production ~(kg~m^-2~year^-1)), 2, 2)
    # CIs
    polygon(c(1:100, 100:1), c(p.99.tr[,2], rev(p.99.tr[,3])), col=rgb(.5, 1, .2),
            border=NA)
    polygon(c(1:100, 100:1), c(p.95.tr[,2], rev(p.95.tr[,3])), col=rgb(0, .8, .5),
            border=NA)
    # fit
    lines(1:100, p.99.tr[,1], ylim=range(p.99.tr), lwd=2)
    #legend
    legend("topleft", legend=c("fit", "99%-CI", "95%-CI"), lty=c(1, NA, NA), lwd=2,
           pch=c(NA, 15, 15), bty="n",
           col=c("#000000", rgb(.5, 1, .2), rgb(0, .8, .5)))
    

    产量

    【讨论】:

    • 感谢您的回答和建议!这很好。但是,我需要 y 轴介于 0 和 1 之间(数据的原始比例)。当我还将年龄更改为介于 0 和 200 之间时,y 轴介于 -30 和 30 之间时,我还希望提取外部 95% CI 的预测,以便模型生成一个可以用灰色填充的多边形颜色。
    • @matrivi 我忘记了反向转换,请参阅编辑。对于您的填充方法,您可能需要查看?polygon,请参阅例如这个答案:stackoverflow.com/a/36948706/6574038
    • 谢谢!这是我在堆栈溢出中的第一个问题,您的回答真的很有帮助!我已经编辑了我的问题以指定我的图形所需的多边形类型。我将继续调查此问题,因为我无法从您建议检查的答案中弄清楚。
    • @matrivi 通常,在 Stack Overflow 中,我们会提出一个新问题,而不是大幅更改问题,但我例外。请参阅我的扩展答案。
    猜你喜欢
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多