简体   繁体   中英

lsmeans for a piecewise linear mixed-effects model on r

I originally posted this question on Cross Validated Stackexchange, and got no answer. Therefore I decided to give it a go here. I am trying to figure out how to obtain lsmeans for a piecewise linear mixed-effects model (fitted with the nlme package) with random intercepts and slopes. My data represent math scores from a group of male and female students taking a test every week before and after the introduction of a daily routine of meditation. A minimal reproducible example to create the data frame and fit the model is as follows:

library(nlme)
library("lsmeans")

# Subject's ID
ID <- c(1,1,1,
        2,2,2,
        3,3,3,
        4,4,4,
        5,5,5,
        6,6,6,
        7,7,7,
        8,8,8)
# Time (weeks) before introduction of routine
time1 <- c(-1,0,0,
           -1,0,0,
           -1,0,0,
           -1,0,0,
           -1,0,0,
           -1,0,0,
           -1,0,0,
           -1,0,0)
# Time (weeks) before introduction of routine
time2 <- c(0,0,1,
           0,0,1,
           0,0,1,
           0,0,1,
           0,0,1,
           0,0,1,
           0,0,1,
           0,0,1)

# week test math scores 
mscore <- c(80,92,73,
           75,80,85,
           60,75,70,
           75,80,75,
           78,84,75,
           78,91,95,
           64,72,71,
           84,92,70)

# create dataframe
longdata <-data.frame(ID, time1, time2, mscore)
head(longdata)

# fit model
pwmodel <- lme(mscore ~ time1+time2,
                      random =~ time1+time2|ID,
                      data=longdata,
                      method="ML")

# calculate marginal means:

#with both variables
lsmeans(pwmodel, ~(time1+time2), 
        at=list(time1=c(-1,0,1), time2=c(-1,0,1)) )

# only with one variable
lsmeans(pwmodel, ~time1, 
        at=list(time1=c(-1,0,1) ))

Here time1 and time2 represent the time before and after the start of the daily meditation routine.

The question is: what is the correct way to obtain lsmeans (or emmeans if that is better) from this model at times -1, 0 and 1? Considering the two time variables or only one of them (either time1 or time2)?

The outputs of both approaches are shown below:

> #with both variables
> lsmeans(pwmodel, ~(time1+time2), 
+         at=list(time1=c(-1,0,1), time2=c(-1,0,1)) )
 time1 time2 lsmean   SE df lower.CL upper.CL
    -1    -1   80.8 5.46  7     67.8     93.7
     0    -1   89.8 5.47  7     76.8    102.7
     1    -1   98.8 5.81  7     85.0    112.5
    -1     0   74.2 2.88  7     67.4     81.1
     0     0   83.2 2.77  7     76.7     89.8
     1     0   92.2 3.28  7     84.5    100.0
    -1     1   67.8 3.34  7     59.9     75.6
     0     1   76.8 3.12  7     69.4     84.1
     1     1   85.8 3.47  7     77.5     94.0

Degrees-of-freedom method: containment 
Confidence level used: 0.95 
> # only with one variable
> lsmeans(pwmodel, ~time1, 
+         at=list(time1=c(-1,0,1) ))
 time1 lsmean   SE df lower.CL upper.CL
    -1     71 2.59  7     64.9     77.1
     0     80 2.38  7     74.4     85.6
     1     89 2.89  7     82.2     95.8

Results are averaged over the levels of: time2 
Degrees-of-freedom method: containment 
Confidence level used: 0.95 

They clearly return different results, but shouldn't both ways give the same value?

You have a very awkward parameterization, in that there is really only one concept of "time", not two. I suggest defining a dataset with only the real time variable, and fitting a model that accounts for the break point at 0:

library(nlme)
library(emmeans)

dat <- data.frame(
    ID = rep(1:8, each = 3),
    time = rep(-1:1, 8),
    mscore = c(80,92,73,
               75,80,85,
               60,75,70,
               75,80,75,
               78,84,75,
               78,91,95,
               64,72,71,
               84,92,70)
)

mod <- lme(mscore ~ time:(1 + (time > 0)), ~ time|ID, data = dat)

lsmeans(mod, "time", cov.reduce = FALSE)
##  time lsmean   SE df lower.CL upper.CL
##    -1   74.2 3.20  7     66.7     81.8
##     0   83.2 2.68  7     76.9     89.6
##     1   76.8 2.88  7     70.0     83.5
## 
## Degrees-of-freedom method: containment 
## Confidence level used: 0.95

emmip(mod, ~ time, at = list(time = seq(-1, 1, by = .25)))

Created on 2021-11-20 by the reprex package (v2.0.0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM