I have made a GLM and am trying to plot the model using ggplot using the following code. I think i need to add the type argument so that my model doesn't just produce a horizontal flat line. However i am struggling to fit it using the type argument as i run into this error message;
Error in model.frame.default(Terms, newdata, na.action = na.action, xlev =
object$xlevels) :
object is not a matrix
Here is my dataset and code used to get this if anyone knows the fix for this
my data (first 10 rows);
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
my code used to create the model and plot
model3 = glm(cases ~ date,
data = aids,
family = poisson(link='log'))
#plotting the model (“link”, “response”, “terms”)
plot_predictions <- function(model, type = 'response') {
#make predictions
preds <- predict(model, df)
#plot
df %>%
ggplot(aes(date, cases)) +
geom_point() +
geom_line(aes(date, preds), col = 'red') +
ggtitle("Model 2 - Poisson GLM predicting cases") +
theme(plot.title = element_text(hjust = 0.5, size = 12, face = 'bold'))
}
plot_predictions(model3, aids)
dput output
dput(head(aids, 10))
structure(list(cases = c(2, 6, 10, 8, 12, 9, 28, 28, 36, 32),
quarter = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L,
2L), .Label = c("1", "2", "3", "4"), class = "factor"), date =
c(83,
83.25, 83.5, 83.75, 84, 84.25, 84.5, 84.75, 85, 85.25)),
row.names = c(NA,
10L), class = "data.frame")
You are reinventing the wheel a bit here. This can be done automatically in ggplot using geom_smooth
ggplot(aids, aes(date, cases)) +
geom_point() +
geom_smooth(col = 'red', se= FALSE, method = glm,
method.args = list(family = poisson(link = 'log'))) +
ggtitle("Model 2 - Poisson GLM predicting cases") +
theme(plot.title = element_text(hjust = 0.5, size = 12, face = 'bold'))
You can even get the standard error to show by omitting se = FALSE
:
ggplot(aids, aes(date, cases)) +
geom_segment(aes(xend = date, yend = 0), color = "deepskyblue4") +
geom_point(size = 3) +
geom_smooth(col = 'red3', fill = "red3", method = glm, alpha = 0.1,
method.args = list(family = poisson(link = 'log'))) +
ggtitle("Model 2 - Poisson GLM predicting cases") +
theme_minimal(base_size = 16) +
theme(plot.title = element_text(hjust = 0.5, face = 'bold'))
Here's one that puts the predictions on the right scale:
library(tidyverse)
aids <- structure(list(cases = c(2, 6, 10, 8, 12, 9, 28, 28, 36, 32),
quarter = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L,
2L), .Label = c("1", "2", "3", "4"), class = "factor"), date =
c(83,
83.25, 83.5, 83.75, 84, 84.25, 84.5, 84.75, 85, 85.25)),
row.names = c(NA,
10L), class = "data.frame")
model3 = glm(cases ~ date,
data = aids,
family = poisson(link='log'))
plot_predictions <- function(model, df, type = 'response') {
require(tidyverse)
#make predictions
preds <- predict(model, df, type= type)
#plot
df %>%
ggplot(aes(date, cases)) +
geom_point() +
geom_line(aes(date, preds), col = 'red') +
ggtitle("Model 2 - Poisson GLM predicting cases") +
theme(plot.title = element_text(hjust = 0.5, size = 12, face = 'bold'))
}
plot_predictions(model3, aids)
Created on 2022-05-25 by the reprex package (v2.0.1)
Here's how you could do it with confidence intervals, though this will only work nicely in bivariate models. I've included an option using ggpredict()
from the ggeffects
package that will work in this and other circumstances. The trick here is that you've got to make the predictions on the link scale, make the confidence intervals from the standard errors of the predictions and then transform everything (fit, lower and upper bounds) through the inverse link.
library(tidyverse)
aids <- structure(list(cases = c(2, 6, 10, 8, 12, 9, 28, 28, 36, 32),
quarter = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L,
2L), .Label = c("1", "2", "3", "4"), class = "factor"), date =
c(83,
83.25, 83.5, 83.75, 84, 84.25, 84.5, 84.75, 85, 85.25)),
row.names = c(NA,
10L), class = "data.frame")
model3 = glm(cases ~ date,
data = aids,
family = poisson(link='log'))
plot_predictions <- function(model, df, conf=.95, type = 'response') {
require(tidyverse)
#make predictions
preds <- predict(model, df, type= "link", se.fit=TRUE)
preds <- as.data.frame(preds[1:2])
preds$x <- df$date
preds <- preds %>%
mutate(lwr = fit - pnorm(1-(1-conf/2))*se.fit,
upr = fit + pnorm(1-(1-conf/2))*se.fit,
across(c(fit, lwr, upr), ~family(model)$linkinv(.x)))
#plot
ggplot(data=df, aes(date, cases)) +
geom_ribbon(data=preds, aes(x=x, y=fit, ymin=lwr, ymax=upr), alpha=.25, fill="red", col="transparent") +
geom_line(data=preds, aes(x, fit), col = 'red') +
geom_point() +
ggtitle("Model 2 - Poisson GLM predicting cases") +
theme(plot.title = element_text(hjust = 0.5, size = 12, face = 'bold'))
}
plot_predictions(model3, aids)
Here's the ggpredict()
option:
library(ggeffects)
g <- ggpredict(model3, terms="date [all]")
plot(g, rawdata=TRUE)
Created on 2022-05-25 by the reprex package (v2.0.1)
You can also do this using broom::augment
to add the predictions of your model to the data and plot that:
model3 %>%
broom::augment() %>%
ggplot(aes(date, cases)) +
geom_point() +
geom_line(aes(date, exp(.fitted)), col = 'red') +
ggtitle("Model 2 - Poisson GLM predicting cases") +
theme(plot.title = element_text(hjust = 0.5, size = 12, face = 'bold'))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.