Researchers assign Control or Enhanced feed to each of 32 calves, balancing the two diets within each of four rooms. They weigh each calf at weeks 0, 2, 4, 6 and 8. These invented records illustrate longitudinal data: measurements collected from the same animals over time.
Both fits use the same calf records and shared calf differences. Which fit allows growth to slow, and how does its AIC compare?
Ask performance to inspect the fit
check_singularity(curved)
[1] FALSE
check_normality(curved)
OK: residuals appear as normally distributed (p = 0.268).
The first check asks whether the estimated spread of calf differences is nearly zero; FALSE means it is not. The second checks the shape of the remaining errors: observed weights minus fitted weights.
Neither result proves that errors at nearby visits are unrelated.
Errors are observed minus fitted weights, also called residuals. These panels examine their shape, patterns against fitted weight and changing spread.
Add the question specific to growth
library("dplyr")d <- d |>mutate(error_kg =residuals(curved, type ="response") )ggplot(d, aes(week, error_kg)) +geom_point(alpha = .35) +stat_summary(fun = mean, geom ="line", colour ="darkorange") +geom_hline(yintercept =0, linetype =2) +labs(x ="Week", y ="Observed minus fitted kg") +theme_minimal()
Does the orange mean-error line still bend with time?
Add the question specific to growth
Choose the prediction conditions
We want to compare the diets for new calves, giving each of the four rooms equal weight. We leave out the fitted weight difference for any particular calf; this difference is called its deviation.
A calf may be heavier than predicted at one visit and again at the next. This extra relationship between errors is called correlation. Here visits are two weeks apart; nlme::corAR1() uses visit numbers 1–5 in that order. lme4 cannot represent this residual correlation, so the optional extension uses nlme explicitly.
library("dplyr")d <- d |>mutate(visit =factor(week, levels =c(0, 2, 4, 6, 8)) )# lme4 cannot fit residual AR(1) correlation. This optional nlme model# retains the calf intercept and one correlated residual process.# visit_index counts two-week visits, so rho describes adjacent visits.d <- d |>mutate(visit_index =match(week, c(0, 2, 4, 6, 8)))library("nlme")ar1 <- nlme::lme( weight_kg ~ diet * week +I(week^2) + room,random =~1| calf,correlation = nlme::corAR1(form =~ visit_index | calf),data = d,method ="REML")summary(ar1)
This nlme model retains a calf intercept and one correlated residual process. It preserves the earlier covariance assumption without adding an independent residual variance. level = 0 leaves out the fitted calf deviations when predicting.