Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post-hoc tests linear mixed model lsmeans error

Tags:

r

lme4

lsmeans

I have a question about running post hoc tests on linear mixed models:

I am running a linear mixed model in lme4 with 3 groups, 5 snakes per group, each group at a different ventilation rate (Vent), measurements taken at different time points (Time), with snake specified as a random effect (ID)

Data subset below:

subset1 <- structure(list(ID = structure(c(5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 
6L, 6L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 
9L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 10L, 10L, 
10L, 10L, 10L, 20L, 20L, 20L, 20L, 20L, 4L, 4L, 4L, 4L, 4L, 11L, 
11L, 11L, 11L, 11L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 12L, 
13L, 14L, 15L, 16L, 17L, 17L, 17L, 17L, 17L), .Label = c("", 
"1_1_2", "10", "10_1_1", "13_1_4", "14_2_4", "15_3_4", "16_1_4", 
"17_2_4", "2_2_1", "5", "5_2_2", "5_2_3", "5_2_4", "5_2_5", "5_2_6", 
"7_1_2", "8", "9", "9_3_1"), class = "factor"), Vent = c(30L, 
30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 
30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 125L, 
125L, 125L, 125L, 125L, 125L, 125L, 125L, 125L, 125L, 125L, 125L, 
125L, 125L, 125L, 125L, 125L, 125L, 125L, 125L, 125L, 125L, 125L, 
125L, 125L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 
250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 250L, 
250L, 250L, 250L, 250L, 250L), Time = c(60L, 80L, 180L, 720L, 
1440L, 60L, 80L, 180L, 720L, 1440L, 60L, 80L, 180L, 720L, 1440L, 
60L, 80L, 180L, 720L, 1440L, 60L, 80L, 180L, 720L, 1440L, 60L, 
80L, 180L, 720L, 1440L, 60L, 80L, 180L, 720L, 1440L, 60L, 80L, 
180L, 720L, 1440L, 60L, 80L, 180L, 720L, 1440L, 60L, 80L, 180L, 
720L, 1440L, 60L, 80L, 180L, 720L, 1440L, 60L, 80L, 180L, 720L, 
1440L, 60L, 80L, 180L, 720L, 1440L, 60L, 80L, 180L, 720L, 1440L, 
60L, 80L, 180L, 720L, 1440L), corr.pO2 = c(224.1388673, 233.9456874, 
239.1553778, 107.2373336, 76.71835625, 164.6293748, 243.8501858, 
234.8205544, 71.74240501, 62.23789874, 69.69478654, 62.23789874, 
152.1142885, 79.61325688, 63.33285001, 240.8713061, 231.304842, 
222.7743953, 95.7912966, 64.41744793, 241.7255035, 238.2936023, 
138.1188987, 43.00663696, 50.64392111, 265.4973967, 274.0599252, 
285.0144919, 83.37647392, NA, 292.3660214, 281.6533627, 275.9747984, 
63.33285001, 56.59660394, 254.2521631, 222.3180596, 208.736288, 
88.83223104, 114.1782867, 208.255285, 232.1878564, 193.3861802, 
72.75355024, 60.01517133, 209.6956308, 245.9596884, 200.4342522, 
75.73874562, 67.61194011, 240.0146049, 261.1278627, 166.9318704, 
74.75152919, 73.75652657, 270.9724687, 251.7882317, 245.9596884, 
147.1396383, 50.64392111, 294.179467, 296.3431178, 284.6426934, 
73.75652657, 75.73874562, 233.0681297, 234.3834557, 143.3247511, 
73.75652657, 66.55672391, 245.9596884, 249.3041163, 223.6847954, 
92.35383362, 78.65544784)), .Names = c("ID", "Vent", "Time", 
"corr.pO2"), row.names = c(NA, 75L), class = "data.frame")

Code:

attach(subset1)

require(lme4)

with.vent = lmer(corr.pO2 ~ Vent * Time + (1|ID),REML = FALSE, data = subset1)

with.vent.no.int = lmer(corr.pO2 ~ Vent + Time + (1|ID),REML = FALSE, data = subset1)

anova(with.vent, with.vent.no.int)
#no significant interaction

Test for effect of vent:

without.vent = lmer(corr.pO2 ~ Time + (1|ID), REML = FALSE, data = subset1)

Compare with with vent:

anova(with.vent.no.int, without.vent)
#no significant effect of ventilation treatment p=0.09199

Test for effect of time:

without.time = lmer(corr.pO2 ~ Vent + (1|ID), data = subset1)

anova(with.vent.no.int, without.time)
# highly significant effect of time on pO2 < 2.2e-16 *** 

So try post hoc test:

require(lsmeans)
lsmeans(with.vent.no.int, pairwise ~ Time, adjust = "tukey", data = subset1)

This is where I get the error which reads:

Error in solve.default(L %*% V0 %*% t(L), L) : 
  Lapack routine dgesv: system is exactly singular: U[1,1] = 0

I can run pairwise tests with a correction using:

pairwise.t.test(corr.pO2, Time, p.adj = "BH", paired = T)

but know this will not work where other variables have an interaction (as is the case with my other data), and where I would like pairwise comparisons between each time point and ventilation regime. Is this possible with lsmeans()?

Thank you for your input, I know likelihood ratio tests are in themselves controversial. I have considered a mixed effects ANOVA, but there are some missing data points which make this impossible. The data was previously analysed by another student as a two way anova, no repeated measures, but my feeling was that this was inappropriate as each snakes was measured at repeated time points

like image 744
Catherine Williams Avatar asked Mar 14 '23 16:03

Catherine Williams


2 Answers

The answer turns out to be fairly simple: you need to make sure that your Vent and Time predictors are factors. Otherwise lsmeans gets confused about the meaning of a pairwise test. (There is a slightly longer conversation to be had about whether you really wanted to analyze this model with continuous predictor, i.e. as a response surface design rather than 2-way ANOVA ...) Here's a slightly more compact version of your analysis:

subset1 <- transform(subset1,Vent=factor(Vent), Time=factor(Time))
require(lme4)
with.vent = lmer(corr.pO2 ~ Vent * Time + (1|ID),
       REML = FALSE, data = subset1)
drop1(with.vent,test="Chisq")  ## test interaction
with.vent.no.int = update(with.vent, . ~ . - Vent:Time)
drop1(with.vent.no.int,test="Chisq")  ## test main effects
require(lsmeans)
lsmeans(with.vent.no.int, pairwise ~ Time)

Subset of output:

$contrasts
 contrast    estimate       SE    df t.ratio p.value
 60 - 80     -6.99222 12.76886 63.45  -0.548  0.9819
 60 - 180    14.74281 12.76886 63.45   1.155  0.7768
 60 - 720   147.27139 12.76886 63.45  11.534  <.0001
...

I do agree that the error message is inscrutable. It might be worth mentioning this to the lsmeans maintainer to see if it's possible to detect and flag this (really very common) error.

like image 86
Ben Bolker Avatar answered Mar 16 '23 17:03

Ben Bolker


The next update for lsmeans (probably around Feb 1, 2016) will catch this kind of error:

> lsmeans(with.vent.no.int, pairwise ~ Vent)

$lsmeans
     Vent   lsmean       SE    df lower.CL upper.CL
 135.1351 167.4871 6.859275 18.63 153.1111  181.863

Confidence level used: 0.95 

$contrasts


Warning message:
In contrast.ref.grid(result, method = contr, by, ...) :
  No contrasts were generated! Perhaps only one lsmean is involved.
  This can happen, for example, when your predictors are not factors.

The ref.grid function is handy for understanding what you've got:

> ref.grid(with.vent.no.int)
'ref.grid' object with variables:
    Vent = 135.14
    Time = 483.24

Both Vent and Time are covariates, so by default their averages are used. To change this, you do not necessarily have to alter the dataset; you can just coerce the predictors to factors in the model:

> repaired = lmer(corr.pO2 ~ factor(Vent) + factor(Time) + (1|ID), 
                  REML = FALSE, data = subset1)
> ref.grid(repaired)
'ref.grid' object with variables:
    Vent =  30, 125, 250
    Time =   60,   80,  180,  720, 1440

> lsmeans(repaired, pairwise ~ Vent)
$lsmeans
 Vent   lsmean       SE    df lower.CL upper.CL
   30 146.0967 12.19373 18.16 120.4952 171.6981
  125 177.0917 12.29417 18.66 151.3274 202.8559
  250 173.2568 11.12879 26.72 150.4111 196.1024

Results are averaged over the levels of: Time 
Confidence level used: 0.95 

$contrasts
 contrast    estimate       SE    df t.ratio p.value
 30 - 125  -30.994975 17.31570 18.41  -1.790  0.2005
 30 - 250  -27.160077 16.50870 21.52  -1.645  0.2490
 125 - 250   3.834898 16.58302 21.81   0.231  0.9710

Results are averaged over the levels of: Time 
P value adjustment: tukey method for comparing a family of 3 estimates 
like image 36
Russ Lenth Avatar answered Mar 16 '23 15:03

Russ Lenth