Author: Oliver Jayasinghe and Rex Parsons

# Mixed models

#### Oliver Jayasinghe and Rex Parsons

    library(GLMMcosinor)
    library(dplyr)
    library(ggplot2)

`{GLMMcosinor}` allows specification of mixed models accounting for fixed and/or random effects. Mixed model specification follows the `{lme4}` format. See their vignette, Fitting Linear Mixed-Effects Models Using lme4, for details about how to specify mixed models.

### Data with subject-level differences

To illustrate an example of using a model with random effects on the cosinor components, we will first simulate some data with `id`-level differences in amplitude and acrophase.

    f_sample_id <- function(id_num,
                            n = 30,
                            mesor,
                            amp,
                            acro,
                            family = "gaussian",
                            sd = 0.2,
                            period,
                            n_components,
                            beta.group = TRUE) {
      data <- simulate_cosinor(
        n = n,
        mesor = mesor,
        amp = amp,
        acro = acro,
        family = family,
        sd = sd,
        period = period,
        n_components = n_components
      )
      data$subject <- id_num
      data
    }

    dat_mixed <- do.call(
      "rbind",
      lapply(1:30, function(x) {
        f_sample_id(
          id_num = x,
          mesor = rnorm(1, mean = 0, sd = 1),
          amp = rnorm(1, mean = 3, sd = 0.5),
          acro = rnorm(1, mean = 1.5, sd = 0.2),
          period = 24,
          n_components = 1
        )
      })
    )
    dat_mixed$subject <- as.factor(dat_mixed$subject)

A quick graph shows how there are individual differences in terms of MESOR, amplitude and phase.

    ggplot(dat_mixed, aes(times, Y, col = subject)) +
      geom_point() +
      geom_line() +
      theme_bw()

### A single component model with random effects

For the model, we should include a random effect for the MESOR, amplitude and acrophase as these are clustered within individuals.

In the model formula, we can use the special `amp_acro[n]` which represents the nth cosinor component. In this case, we only have one component so we use `amp_acro1`. Following the `{lme4}`-style mixed model formula, we add our random effect for this component and the intercept term (MESOR) clustered within subjects by using `(1 + amp_acro1 | subject)`. The code below fits this model

    mixed_mod <- cglmm(
        Y ~ amp_acro(times, n_components = 1, period = 24) +
          (1 + amp_acro1 | subject),
        data = dat_mixed
      )

This works by replacing the amp_acro1 with the relevant cosinor components when the data is rearranged and the formula created. The formula created can be accessed using `.$formula`, and shows the `amp_acro1` is replaced by the `main_rrr1` and `main_sss1` (the cosine and sine components of time that also appear in the fixed effects).

    mixed_mod$formula
    #> Y ~ main_rrr1 + main_sss1 + (1 + main_rrr1 + main_sss1 | subject)
    #> <environment: 0x000001d112b85738>

The mixed model can also be plotted using `autoplot`, but some of the plotting features that are available for fixed-effects models may not be available for mixed-effect models.

    autoplot(mixed_mod, superimpose.data = TRUE)

The summary of the model shows that the input means for MESOR, amplitude and acrophase are similar to what we specified in the simulation (0, 3, and 1.5, respectively).

    summary(mixed_mod)
    #>
    #>  Conditional Model
    #> Raw model coefficients:
    #>                estimate standard.error    lower.CI upper.CI p.value
    #> (Intercept) -0.09323335     0.17907993 -0.44422356  0.25776 0.60263
    #> main_rrr1    0.18030389     0.11089882 -0.03705381  0.39766 0.10398
    #> main_sss1    2.85563791     0.09447410  2.67047207  3.04080 < 2e-16 ***
    #> ---
    #> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
    #>
    #> Transformed coefficients:
    #>                estimate standard.error    lower.CI upper.CI p.value
    #> (Intercept) -0.09323335     0.17907993 -0.44422356  0.25776 0.60263
    #> amp1         2.86132441     0.09431188  2.67647651  3.04617 < 2e-16 ***
    #> acr1         1.50774041     0.03880609  1.43168187  1.58380 < 2e-16 ***
    #> ---
    #> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

We can see that the predicted values from the model closely resemble the patterns we see in the input data.

    ggplot(cbind(dat_mixed, pred = predict(mixed_mod))) +
      geom_point(aes(x = times, y = Y, col = subject)) +
      geom_line(aes(x = times, y = pred, col = subject))

This looks like a good model fit for these data. We can highlight the importance of using a mixed model in this situation rather than a fixed effects only model by creating that (bad) model and comparing the two by using the Akaike information criterion using `AIC()`.

    fixed_effects_mod <- cglmm(
      Y ~ amp_acro(times, n_components = 1, period = 24),
      data = dat_mixed
    )

    AIC(fixed_effects_mod$fit)
    #> [1] 2834.918
    AIC(mixed_mod$fit)
    #> [1] 144.208

Aside from not being able to be useful to see the differences between subjects from the model, we end up with much worse model fit and likely biased and/or imprecise estimates of our fixed effects that we are interested in!