I have several datasets in which it would make a lot more sense if the date were coded as a circular variable rather than linear. I also want a quadratic (or more) effect. However I cannot find a proper way to do that in a GLMM and I wonder if it is at all possible.
Here an example:
library(tidyverse)
library(glmmTMB)
library(ggeffects)
data(airquality)
airquality$Date = as.Date(paste0("2018-", airquality$Day, "-", airquality$Month))
airquality$JulianDay = yday(airquality$Date)
airquality = airquality %>%
drop_na(Date)
# Create circular date
airquality$Date_cos=cos(airquality$JulianDay*(2*pi/365))
airquality$Date_sin=sin(airquality$JulianDay*(2*pi/365))
Mod1=glmmTMB(Ozone ~ poly((Date_sin + Date_cos), 2), # my attempt
data = airquality,
family = poisson)
Mod2=glmmTMB(Ozone ~ poly(JulianDay, 2), # a regular model for comparison
data = airquality,
family = poisson)
# predict values
pred1 = ggpredict(Mod1, terms = c("Date_sin [all]", "Date_cos [all]"))
pred2 = ggpredict(Mod2, terms = c("JulianDay [all]"))
# Back-transform to find Julian Day
func=function(x,y){ifelse(x<0,2*pi-acos(y),acos(y))}
pred1$JulianDay=mapply(func,x=pred1$x,y=as.numeric(as.character(pred1$group)))*(365/(2*pi)) pred1$Date=as.Date(strptime(pred1$JulianDay, "%j"))
# Plot with circular date
ggplot(pred1, aes (JulianDay, predicted)) +
geom_line()
# Plot with linear date
ggplot(pred2, aes (x, predicted)) +
geom_line()
As you see my attempt leads to an unrealistic result but I don't know if it comes from the GLMM process or from the function to backtransform the sin/cos values.