创建和绘制置信区间
Creating and plotting confidence intervals
我已经为我的数据拟合了一个高斯 GLM 模型,我现在希望创建 95% CIs 并将它们拟合到我的数据中。我在绘图时遇到了几个问题,因为我无法让它们捕获我的数据,它们似乎只是绘制了与模型相同的线而没有捕获数据点。此外,我也不确定我是否以正确的方式在此处创建了 CIs 的均值。如果有人知道如何解决这个问题,我在下面输入了我的数据和代码
使用的数据
aids
cases quarter date
1 2 1 83.00
2 6 2 83.25
3 10 3 83.50
4 8 4 83.75
5 12 1 84.00
6 9 2 84.25
7 28 3 84.50
8 28 4 84.75
9 36 1 85.00
10 32 2 85.25
11 46 3 85.50
12 47 4 85.75
13 50 1 86.00
14 61 2 86.25
15 99 3 86.50
16 95 4 86.75
17 150 1 87.00
18 143 2 87.25
19 197 3 87.50
20 159 4 87.75
21 204 1 88.00
22 168 2 88.25
23 196 3 88.50
24 194 4 88.75
25 210 1 89.00
26 180 2 89.25
27 277 3 89.50
28 181 4 89.75
29 327 1 90.00
30 276 2 90.25
31 365 3 90.50
32 300 4 90.75
33 356 1 91.00
34 304 2 91.25
35 307 3 91.50
36 386 4 91.75
37 331 1 92.00
38 368 2 92.25
39 416 3 92.50
40 374 4 92.75
41 412 1 93.00
42 358 2 93.25
43 416 3 93.50
44 414 4 93.75
45 496 1 94.00
我的代码用于在绘图之前创建模型和间隔
#creating the model
model3 = glm(cases ~ date,
data = aids,
family = poisson(link='log'))
#now to add approx. 95% confidence envelope around this line
#predict again but at the linear predictor level along with standard errors
my_preds <- predict(model3, newdata=data.frame(aids), se.fit=T, type="link")
#calculate CI limit since linear predictor is approx. Gaussian
upper <- my_preds$fit+1.96*my_preds$se.fit #this might be logit not log
lower <- my_preds$fit-1.96*my_preds$se.fit
#transform the CI limit to get one at the level of the mean
upper <- exp(upper)/(1+exp(upper))
lower <- exp(lower)/(1+exp(lower))
#plotting data
plot(aids$date, aids$cases,
xlab = 'Date', ylab = 'Cases', pch = 20)
#adding CI lines
plot(aids$date, exp(my_preds$fit), type = "link",
xlab = 'Date', ylab = 'Cases') #add title
lines(aids$date,exp(my_preds$fit+1.96*my_preds$se.fit),lwd=2,lty=2)
lines(aids$date,exp(my_preds$fit-1.96*my_preds$se.fit),lwd=2,lty=2)
我目前没有数据点的结果,这里的模型是正确的,但是 CI 不是因为我没有数据点,所以 CI 是错误的,我认为在某个地方
编辑:对OP提供完整数据集的回应。
这最初是关于在同一图表上绘制数据和模型的问题,但已经发生了很大变化。您似乎对原始问题有答案。下面是解决其余问题的一种方法。
看看你的(和我的)图,泊松 glm 显然不是一个好的模型。换句话说,案例数量可能会随日期而变化,但也会受到模型中不存在的其他因素(外部回归变量)的影响。
仅绘制您的数据强烈表明您至少有两种甚至更多的制度:病例增长遵循不同模型的时间框架。
ggplot(aids, aes(x=date)) + geom_point(aes(y=cases))
这表明 segmented regression。与 R 中的大多数东西一样,有一个包(实际上不止一个)。下面的代码使用 segmented
包使用 1 个断点(两个区域)构建连续的泊松 glm。
library(data.table)
library(ggplot2)
library(segmented)
setDT(aids) # convert aids to a data.table
aids[, pred:=
predict(
segmented(glm(cases~date, .SD, family = poisson), seg.Z = ~date, npsi=1),
type='response', se.fit=TRUE)$fit]
ggplot(aids, aes(x=date))+ geom_line(aes(y=pred))+ geom_point(aes(y=cases))
请注意,我们需要告诉 segmented
断点的数量,而不是断点的位置 - 算法会为您计算出来。所以在这里,我们看到 3Q87 之前的状态使用泊松 glm 很好地建模,而之后的状态则不是。这是一种奇特的说法,即 87 年 3 季度左右“发生了一些事情”,它改变了疾病的进程(至少在这个数据中是这样)。
下面的代码做同样的事情,但有 1 到 4 个断点。
get.pred <- \(p.n, p.DT) {
fit <- glm(cases~date, p.DT, family=poisson)
seg.fit <- segmented(fit, seg.Z = ~date, npsi=p.n)
predict(seg.fit, type='response', se.fit=TRUE)[c('fit', 'se.fit')]
}
gg.dt <- rbindlist(lapply(1:4, \(x) { copy(aids)[, c('pred', 'se'):=get.pred(x, .SD)][, npsi:=x] } ))
ggplot(gg.dt, aes(x=date))+
geom_ribbon(aes(ymin=pred-1.96*se, ymax=pred+1.96*se), fill='grey80')+
geom_line(aes(y=pred))+
geom_point(aes(y=cases))+
facet_wrap(~npsi)
请注意,第一个断点的位置似乎没有改变,而且,尽管使用了泊松 glm,但除第一个区域外,所有区域的增长都是线性的。
包文档中描述了 goodness-of-fit 指标,可以帮助您确定有多少断点与您的数据最一致。
最后,还有 mcp
包,它更强大一些,但使用起来也更复杂一些。
原始响应:这是构建模型预测和标准的一种方法。 data.table
中的错误,然后使用 ggplot
.
绘图
library(data.table)
library(ggplot2)
setDT(aids) # convert aids to a data.table
aids[, c('pred', 'se', 'resid.scale'):=predict(glm(cases~date, data=.SD, family=poisson), type='response', se.fit=TRUE)]
ggplot(aids, aes(x=date))+
geom_ribbon(aes(ymin=pred-1.96*se, ymax=pred+1.96*se), fill='grey80')+
geom_line(aes(y=pred))+
geom_point(aes(y=cases))
或者,您可以让 ggplot
为您完成所有工作。
ggplot(aids, aes(x=date, y=cases))+
stat_smooth(method = glm, method.args=list(family=poisson))+
geom_point()
我已经为我的数据拟合了一个高斯 GLM 模型,我现在希望创建 95% CIs 并将它们拟合到我的数据中。我在绘图时遇到了几个问题,因为我无法让它们捕获我的数据,它们似乎只是绘制了与模型相同的线而没有捕获数据点。此外,我也不确定我是否以正确的方式在此处创建了 CIs 的均值。如果有人知道如何解决这个问题,我在下面输入了我的数据和代码
使用的数据
aids
cases quarter date
1 2 1 83.00
2 6 2 83.25
3 10 3 83.50
4 8 4 83.75
5 12 1 84.00
6 9 2 84.25
7 28 3 84.50
8 28 4 84.75
9 36 1 85.00
10 32 2 85.25
11 46 3 85.50
12 47 4 85.75
13 50 1 86.00
14 61 2 86.25
15 99 3 86.50
16 95 4 86.75
17 150 1 87.00
18 143 2 87.25
19 197 3 87.50
20 159 4 87.75
21 204 1 88.00
22 168 2 88.25
23 196 3 88.50
24 194 4 88.75
25 210 1 89.00
26 180 2 89.25
27 277 3 89.50
28 181 4 89.75
29 327 1 90.00
30 276 2 90.25
31 365 3 90.50
32 300 4 90.75
33 356 1 91.00
34 304 2 91.25
35 307 3 91.50
36 386 4 91.75
37 331 1 92.00
38 368 2 92.25
39 416 3 92.50
40 374 4 92.75
41 412 1 93.00
42 358 2 93.25
43 416 3 93.50
44 414 4 93.75
45 496 1 94.00
我的代码用于在绘图之前创建模型和间隔
#creating the model
model3 = glm(cases ~ date,
data = aids,
family = poisson(link='log'))
#now to add approx. 95% confidence envelope around this line
#predict again but at the linear predictor level along with standard errors
my_preds <- predict(model3, newdata=data.frame(aids), se.fit=T, type="link")
#calculate CI limit since linear predictor is approx. Gaussian
upper <- my_preds$fit+1.96*my_preds$se.fit #this might be logit not log
lower <- my_preds$fit-1.96*my_preds$se.fit
#transform the CI limit to get one at the level of the mean
upper <- exp(upper)/(1+exp(upper))
lower <- exp(lower)/(1+exp(lower))
#plotting data
plot(aids$date, aids$cases,
xlab = 'Date', ylab = 'Cases', pch = 20)
#adding CI lines
plot(aids$date, exp(my_preds$fit), type = "link",
xlab = 'Date', ylab = 'Cases') #add title
lines(aids$date,exp(my_preds$fit+1.96*my_preds$se.fit),lwd=2,lty=2)
lines(aids$date,exp(my_preds$fit-1.96*my_preds$se.fit),lwd=2,lty=2)
我目前没有数据点的结果,这里的模型是正确的,但是 CI 不是因为我没有数据点,所以 CI 是错误的,我认为在某个地方
编辑:对OP提供完整数据集的回应。
这最初是关于在同一图表上绘制数据和模型的问题,但已经发生了很大变化。您似乎对原始问题有答案。下面是解决其余问题的一种方法。
看看你的(和我的)图,泊松 glm 显然不是一个好的模型。换句话说,案例数量可能会随日期而变化,但也会受到模型中不存在的其他因素(外部回归变量)的影响。
仅绘制您的数据强烈表明您至少有两种甚至更多的制度:病例增长遵循不同模型的时间框架。
ggplot(aids, aes(x=date)) + geom_point(aes(y=cases))
这表明 segmented regression。与 R 中的大多数东西一样,有一个包(实际上不止一个)。下面的代码使用 segmented
包使用 1 个断点(两个区域)构建连续的泊松 glm。
library(data.table)
library(ggplot2)
library(segmented)
setDT(aids) # convert aids to a data.table
aids[, pred:=
predict(
segmented(glm(cases~date, .SD, family = poisson), seg.Z = ~date, npsi=1),
type='response', se.fit=TRUE)$fit]
ggplot(aids, aes(x=date))+ geom_line(aes(y=pred))+ geom_point(aes(y=cases))
请注意,我们需要告诉 segmented
断点的数量,而不是断点的位置 - 算法会为您计算出来。所以在这里,我们看到 3Q87 之前的状态使用泊松 glm 很好地建模,而之后的状态则不是。这是一种奇特的说法,即 87 年 3 季度左右“发生了一些事情”,它改变了疾病的进程(至少在这个数据中是这样)。
下面的代码做同样的事情,但有 1 到 4 个断点。
get.pred <- \(p.n, p.DT) {
fit <- glm(cases~date, p.DT, family=poisson)
seg.fit <- segmented(fit, seg.Z = ~date, npsi=p.n)
predict(seg.fit, type='response', se.fit=TRUE)[c('fit', 'se.fit')]
}
gg.dt <- rbindlist(lapply(1:4, \(x) { copy(aids)[, c('pred', 'se'):=get.pred(x, .SD)][, npsi:=x] } ))
ggplot(gg.dt, aes(x=date))+
geom_ribbon(aes(ymin=pred-1.96*se, ymax=pred+1.96*se), fill='grey80')+
geom_line(aes(y=pred))+
geom_point(aes(y=cases))+
facet_wrap(~npsi)
请注意,第一个断点的位置似乎没有改变,而且,尽管使用了泊松 glm,但除第一个区域外,所有区域的增长都是线性的。
包文档中描述了 goodness-of-fit 指标,可以帮助您确定有多少断点与您的数据最一致。
最后,还有 mcp
包,它更强大一些,但使用起来也更复杂一些。
原始响应:这是构建模型预测和标准的一种方法。 data.table
中的错误,然后使用 ggplot
.
library(data.table)
library(ggplot2)
setDT(aids) # convert aids to a data.table
aids[, c('pred', 'se', 'resid.scale'):=predict(glm(cases~date, data=.SD, family=poisson), type='response', se.fit=TRUE)]
ggplot(aids, aes(x=date))+
geom_ribbon(aes(ymin=pred-1.96*se, ymax=pred+1.96*se), fill='grey80')+
geom_line(aes(y=pred))+
geom_point(aes(y=cases))
或者,您可以让 ggplot
为您完成所有工作。
ggplot(aids, aes(x=date, y=cases))+
stat_smooth(method = glm, method.args=list(family=poisson))+
geom_point()