Longitudinal data: change through time

Week 11 · Essential teaching in class

Gavin Simpson

Aarhus University

Wednesday, 18 November 2026

Read the same calf study

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.

library("dplyr")

library("lme4")
library("performance")
library("marginaleffects", warn.conflicts = FALSE)
library("ggplot2")
d <- readr::read_csv("data/calf-growth.csv")
d <- d |>
  mutate(
    diet = factor(diet, levels = c("Control", "Enhanced")),
    room = factor(room),
    calf = factor(calf),
    week = time_week
  )
head(d |> select("calf", "diet", "week", "weight_kg"), 3)

week counts weeks since researchers assigned the diets. They record week 0 before feeding starts.

Read the same calf study

# A tibble: 3 × 4
  calf  diet     week weight_kg
  <fct> <fct>   <dbl>     <dbl>
1 C01   Control     0      47.9
2 C01   Control     2      58.6
3 C01   Control     4      65.8

Today: how does growth change?

Time Work
08:00–08:45 Recall and time relationships
08:45–09:10 Trajectory detective
09:10–09:25 Break
09:25–10:25 Fit, predict and check
10:25–10:40 Break
10:40–11:30 Own projects and reports

Opening recall: what was assigned?

A calf keeps its assigned diet for eight weeks. Weighing it again does not assign another diet.

  • To how many calves do researchers assign a diet?
  • What do repeated weights tell us about the same calf?
  • How does this differ from Class 10’s crossover study, where an animal receives both treatments in a planned order?

Look at each calf’s path

ggplot(d, aes(week, weight_kg, group = calf, colour = diet)) +
  geom_line(alpha = .4) +
  labs(x = "Week", y = "Weight (kg)") +
  theme_minimal()

Each line joins one calf’s five weights. Do calves start at different weights, and does their gain appear to slow?

Treat visits as groups or use numerical weeks?

A separate mean for each visit A chosen relationship with weeks
Fits the observed visits flexibly Describes a line or curve
Does not describe gaps between visits Can describe values between visits
Estimates more separate mean weights Assumes a particular shape

Both must still account for weights from the same calf.

Fit a straight growth line

Some calves remain heavier than others after allowing for diet and room. (1 | calf) gives each calf a shared weight difference, called a random intercept.

linear <- lmer(
  weight_kg ~ diet * week + room + (1 | calf),
  data = d,
  REML = TRUE
)
summary(linear)

diet * week allows each diet a different starting weight and growth rate. A difference in growth rates is a diet-by-time interaction. We include room because researchers assigned both diets within each room.

Fit a straight growth line

Linear mixed model fit by REML ['lmerMod']
Formula: weight_kg ~ diet * week + room + (1 | calf)
   Data: d

REML criterion at convergence: 748.1

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.52444 -0.54958  0.06794  0.63671  2.19582 

Random effects:
 Groups   Name        Variance Std.Dev.
 calf     (Intercept) 28.957   5.381   
 Residual              3.227   1.796   
Number of obs: 160, groups:  calf, 32

Fixed effects:
                  Estimate Std. Error t value
(Intercept)       39.25054    2.16935  18.093
dietEnhanced       0.20788    1.96511   0.106
week               4.53100    0.07101  63.810
roomR2             0.05862    2.72041   0.022
roomR3             2.40960    2.72041   0.886
roomR4             4.03347    2.72041   1.483
dietEnhanced:week  0.42749    0.10042   4.257

Correlation of Fixed Effects:
            (Intr) dtEnhn week   roomR2 roomR3 roomR4
dietEnhancd -0.453                                   
week        -0.131  0.145                            
roomR2      -0.627  0.000  0.000                     
roomR3      -0.627  0.000  0.000  0.500              
roomR4      -0.627  0.000  0.000  0.500  0.500       
dtEnhncd:wk  0.093 -0.204 -0.707  0.000  0.000  0.000

A difference in growth rate

The straight model’s week coefficient is Control’s gain in kg per week.

dietEnhanced:week is the extra gain per week for Enhanced.

The diet coefficient alone describes the week-0 difference.

Our question: by week 8, how much heavier is the expected Enhanced calf than the expected Control calf?

Let growth slow down

Calves may gain weight quickly at first and more slowly later. I(week^2) lets both diet paths bend by the same amount; this shared bend is called common curvature.

curved <- lmer(
  weight_kg ~ diet * week + I(week^2) + room + (1 | calf),
  data = d,
  REML = TRUE
)
summary(curved)

A negative squared-week coefficient bends the path downwards. It does not mean calves lose weight.

Let growth slow down

Linear mixed model fit by REML ['lmerMod']
Formula: weight_kg ~ diet * week + I(week^2) + room + (1 | calf)
   Data: d

REML criterion at convergence: 725.7

Scaled residuals: 
     Min       1Q   Median       3Q      Max 
-2.27062 -0.60674  0.06788  0.62813  2.19214 

Random effects:
 Groups   Name        Variance Std.Dev.
 calf     (Intercept) 29.084   5.393   
 Residual              2.595   1.611   
Number of obs: 160, groups:  calf, 32

Fixed effects:
                  Estimate Std. Error t value
(Intercept)       38.39388    2.17105  17.684
dietEnhanced       0.20787    1.95706   0.106
week               5.38766    0.16500  32.652
I(week^2)         -0.10708    0.01903  -5.628
roomR2             0.05862    2.72041   0.022
roomR3             2.40960    2.72041   0.886
roomR4             4.03347    2.72041   1.483
dietEnhanced:week  0.42749    0.09005   4.747

Correlation of Fixed Effects:
            (Intr) dtEnhn week   I(w^2) roomR2 roomR3 roomR4
dietEnhancd -0.451                                          
week        -0.110  0.050                                   
I(week^2)    0.070  0.000 -0.923                            
roomR2      -0.627  0.000  0.000  0.000                     
roomR3      -0.627  0.000  0.000  0.000  0.500              
roomR4      -0.627  0.000  0.000  0.000  0.500  0.500       
dtEnhncd:wk  0.083 -0.184 -0.273  0.000  0.000  0.000  0.000

Compare the same observations

# Compare mean relationships by ML; retain REML fits for estimation.
linear_ml <- update(linear, REML = FALSE)
curved_ml <- update(curved, REML = FALSE)
AIC(linear_ml, curved_ml)
          df      AIC
linear_ml  9 774.4759
curved_ml 10 747.5685

AIC compares fit after allowing for extra model terms. A smaller value is better on that comparison; it does not establish every assumption.

We still need to inspect errors and consider how repeated weights are related.

Trajectory detective: explain a growth story

Each card describes an imagined calf study: different growth rates, slowing growth, nearby errors, or illness-related missed visits.

Sketch what the weights might look like. Name:

  1. A line or curve that could describe average growth.
  2. A reason two weights might be related.
  3. Information you need before analysis.

Swap explanations with another group. Break 09:10–09:25.