Search code examples
lme4r-lavaan

How to constrain a parameter in a mixed effect model in R?


I'm trying to fit a mixed effect model with a constrained parameter, and am struggling to make it work. Adding a small bit of complexity, is that one of the terms should be a polynomial.

Essentially what I'm looking for is something like the following, where var 1 is fixed at a certain value.

mod1 <- lmer(outcome ~ var1 + poly(var2,2) + (1 | Study), df)

It seems like it can be done using lmer with the Nelder-Mead option, but I can quite wrap my head around how to make it work.

I've also tried using the lavaan package, but I've never used it before and am getting hung up somewhere. Here is an example...

library(lavaan)

reprex_df <- structure(list(outcome = c(0.54, 5.06, 15.35, 5.4, 5.3, 1.57, 
                                        2.11, 2.71, 9.09, 7.96, 28.8, 4.4, 3.38, 15.43, 4.05), var1 = c(0.55, 
                                                                                                        3.42, 2.24, 2.24, 3.44, 1.82, 1.82, 2.23, 5.41, 2.61, 6.94, 3.98, 
                                                                                                        2.23, 5.29, 3.28), var2 = c(111, 235, 60, 197, 369, 342.78, 240.99, 
                                                                                                                                    406.5, 264, 263.8, 76, 679, 338, 116, 683), study = c("Study 1", 
                                                                                                                                                                                   "Study 2",  "Study 2",  "Study 2", "Study 3", 
                                                                                                                                                                                   "Study 4", "Study 4", "Study 6", "Study 5", 
                                                                                                                                                                                   "Study 7", "Study 2", "Study 7", "Study 6", 
                                                                                                                                                                                   "Study 5", "Study 2")), row.names = c(NA, -15L), class = c("tbl_df", "tbl", "data.frame"))

I think I can make a basic model (without the polynomial)

reprex_df

test.model <- '  outcome  ~ var1 + var2 + study'

test.model <- sem(test.model, 
                    data = reprex_df, cluster = "study")
coef(test.model)

But when I try and constrain var1 to a specific value I'm getting an error

test.model.constr <- '  outcome    ~ var1 + var2 + study

var1 == 4.87
'

test.model.constr <- sem(test.model.constr, 
                  data = reprex_df, cluster = "study")

Any help in constraining the parameter (using either lmer or lavaan) and/or adding a polynomial term in lavaan would be very much appreciated.


Solution

  • It's tricky because lmer "profiles out" the fixed-effect parameters, i.e. they're not explicitly fitted as part of the nonlinear optimization step.

    Assuming var1 is numeric/continuous and we want to set a coefficient of b, how about

    mod1 <- lmer(outcome ~ 1 + offset(b*var1) + poly(var2,2) + (1 | Study), df)
    

    ? This adds the term b*var1 directly to the model.

    The glmmTMB package has a map argument that allows the user to fix any of the parameters explicitly to a particular value (or to constrain several parameters to have a common value).