These notes build on the prior chapters’ R Code and Instructions, where we discuss some operational aspects of R and detail the use of many functions and how to install packages. Here, we skip details that have already been discussed in the prior R Code and Instructions.
Load the AMCP package to use the data from Table 1, Chapter 15.
library(AMCP)
data(chapter_15_table_1)
chapter_15_table_1
## Months30 Months36 Months42 Months48
## 1 108 96 110 122
## 2 103 117 127 133
## 3 96 107 106 107
## 4 84 85 92 99
## 5 118 125 125 116
## 6 110 107 96 91
## 7 129 128 123 128
## 8 90 84 101 113
## 9 84 104 100 88
## 10 96 100 103 105
## 11 105 114 105 112
## 12 113 117 132 130
Margin means
# Means by row (individual here)
apply(chapter_15_table_1, MARGIN=1, FUN=mean)
## [1] 109 120 104 90 121 101 127 97 94 101 109 123
# Means by column (measurement occasion here)
apply(chapter_15_table_1, MARGIN=2, FUN=mean)
## Months30 Months36 Months42 Months48
## 103 107 110 112
First, we need to convert the structure of the data from “wide” or “multivariate” to “long” or “univariate.” We find the easiest way to do this is using the tidyr and dplyr packages.
library(tidyr)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# Add an ID variable (by row number)
chapter_15_table_1$ID <- 1:nrow(chapter_15_table_1)
# Note that the "sep=-3" partitions between the 3rd and 2nd value from the end.
# The "-ID" here means to leave ID as it is (i.e., without "gathering" it)
data = chapter_15_table_1 %>%
gather(key=Unit.Month, value=Values, -ID) %>%
separate(col=Unit.Month, into=c("Unit", "Month"), sep=-3) %>%
arrange(ID, Month)
# Display the data
data
## ID Unit Month Values
## 1 1 Months 30 108
## 2 1 Months 36 96
## 3 1 Months 42 110
## 4 1 Months 48 122
## 5 2 Months 30 103
## 6 2 Months 36 117
## 7 2 Months 42 127
## 8 2 Months 48 133
## 9 3 Months 30 96
## 10 3 Months 36 107
## 11 3 Months 42 106
## 12 3 Months 48 107
## 13 4 Months 30 84
## 14 4 Months 36 85
## 15 4 Months 42 92
## 16 4 Months 48 99
## 17 5 Months 30 118
## 18 5 Months 36 125
## 19 5 Months 42 125
## 20 5 Months 48 116
## 21 6 Months 30 110
## 22 6 Months 36 107
## 23 6 Months 42 96
## 24 6 Months 48 91
## 25 7 Months 30 129
## 26 7 Months 36 128
## 27 7 Months 42 123
## 28 7 Months 48 128
## 29 8 Months 30 90
## 30 8 Months 36 84
## 31 8 Months 42 101
## 32 8 Months 48 113
## 33 9 Months 30 84
## 34 9 Months 36 104
## 35 9 Months 42 100
## 36 9 Months 48 88
## 37 10 Months 30 96
## 38 10 Months 36 100
## 39 10 Months 42 103
## 40 10 Months 48 105
## 41 11 Months 30 105
## 42 11 Months 36 114
## 43 11 Months 42 105
## 44 11 Months 48 112
## 45 12 Months 30 113
## 46 12 Months 36 117
## 47 12 Months 42 132
## 48 12 Months 48 130
#Note that we do not need "Unit" variable, so we drop it.
data$Unit <- NULL
# Examining the structure of the data.
str(data)
## 'data.frame': 48 obs. of 3 variables:
## $ ID : int 1 1 1 1 2 2 2 2 3 3 ...
## $ Month : chr "30" "36" "42" "48" ...
## $ Values: int 108 96 110 122 103 117 127 133 96 107 ...
# Examining the structure of the data we saw that "Month" is being treated as a character variable,
# yet we want it to be numeric:
data$Month <- as.numeric(data$Month)
str(data)
## 'data.frame': 48 obs. of 3 variables:
## $ ID : int 1 1 1 1 2 2 2 2 3 3 ...
## $ Month : num 30 36 42 48 30 36 42 48 30 36 ...
## $ Values: int 108 96 110 122 103 117 127 133 96 107 ...
There are multiple ways of producing trajectory plots. One convenient way is using the xyplot() function from the lattice. The lattice package provides a great deal of flexibility.
library(lattice)
# (each ID has it's own plot)
xyplot(Values ~ Month | ID, data=data, type="l", main="Trajectory Plot of McCarthy Scores", ylab="ID", xlab="Time in Months")
Another way of plotting indivivdual trajectories is with ggplot2. The ggplot2 package provides a great deal of flexibility.
library(ggplot2)
Base.Plot <- ggplot(data = data, aes(x = Month, y = Values, group = ID))
Base.Plot + geom_line()
Yes another way to observe the trajectories is using vit() function from the MBESS package, which is easy to use but much less flexible than are the lattice or ggplot2 packages.
library(MBESS)
vit(id = "ID", occasion = "Month", score = "Values", Data = data)
#Or, without points
vit(id = "ID", occasion = "Month", score = "Values", pch="", Data = data)
A general linear model (GLM) appraoch to the data from Table 15.1 (compare this to Table 15.2 in MDK).
Model.GLM <- lm(Values ~ as.factor(Month) + as.factor(ID), data=data)
summary(Model.GLM)
##
## Call:
## lm(formula = Values ~ as.factor(Month) + as.factor(ID), data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -14.00 -4.25 0.00 4.25 14.00
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.040e+02 4.358e+00 23.862 < 2e-16 ***
## as.factor(Month)36 4.000e+00 3.183e+00 1.257 0.21769
## as.factor(Month)42 7.000e+00 3.183e+00 2.199 0.03498 *
## as.factor(Month)48 9.000e+00 3.183e+00 2.828 0.00791 **
## as.factor(ID)2 1.100e+01 5.513e+00 1.995 0.05433 .
## as.factor(ID)3 -5.000e+00 5.513e+00 -0.907 0.37102
## as.factor(ID)4 -1.900e+01 5.513e+00 -3.446 0.00157 **
## as.factor(ID)5 1.200e+01 5.513e+00 2.177 0.03676 *
## as.factor(ID)6 -8.000e+00 5.513e+00 -1.451 0.15619
## as.factor(ID)7 1.800e+01 5.513e+00 3.265 0.00255 **
## as.factor(ID)8 -1.200e+01 5.513e+00 -2.177 0.03676 *
## as.factor(ID)9 -1.500e+01 5.513e+00 -2.721 0.01031 *
## as.factor(ID)10 -8.000e+00 5.513e+00 -1.451 0.15619
## as.factor(ID)11 -6.527e-15 5.513e+00 0.000 1.00000
## as.factor(ID)12 1.400e+01 5.513e+00 2.539 0.01600 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.797 on 33 degrees of freedom
## Multiple R-squared: 0.7815, Adjusted R-squared: 0.6888
## F-statistic: 8.432 on 14 and 33 DF, p-value: 2.753e-07
anova(Model.GLM)
## Analysis of Variance Table
##
## Response: Values
## Df Sum Sq Mean Sq F value Pr(>F)
## as.factor(Month) 3 552 184.00 3.0269 0.04322 *
## as.factor(ID) 11 6624 602.18 9.9063 1.314e-07 ***
## Residuals 33 2006 60.79
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
The lme4 package is a widely used package for mixed-effects models or hierarchical linear models, or what is often termed multilevel models, in R. Notice, below, that the fixed effects are provided (the intercept is included by default) and the random effects are included in parentheses, with an pipe symbol (i.e., “|”) used to denote the nesting strucutre. Here, the “(1|ID)” part, in words, means that the “intercept is nested within ID,” which means that there is a random intercept for each ID. We fit the model in two ways, one where Month is treated as a factor (directly below) and in the a future code-chunk, Month is treated continuous. To be clear, notice that the way SAS (as shown in the book) and R code the factor is different, as SAS takes the last ID whereas R takes the first, although the model parameterizations are done differently, they are equivalent. Compare this to Table 15.3 in MDK.
library(lme4)
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
## The following object is masked from 'package:tidyr':
##
## expand
Model.Cat <- lmer(Values ~ as.factor(Month) + (1|ID), data=data)
summary(Model.Cat)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ as.factor(Month) + (1 | ID)
## Data: data
##
## REML criterion at convergence: 340.8
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.88627 -0.44709 -0.09063 0.53924 1.70501
##
## Random effects:
## Groups Name Variance Std.Dev.
## ID (Intercept) 135.35 11.634
## Residual 60.79 7.797
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 103.000 4.043 25.477
## as.factor(Month)36 4.000 3.183 1.257
## as.factor(Month)42 7.000 3.183 2.199
## as.factor(Month)48 9.000 3.183 2.828
##
## Correlation of Fixed Effects:
## (Intr) a.(M)3 a.(M)42
## as.fct(M)36 -0.394
## as.fct(M)42 -0.394 0.500
## as.fct(M)48 -0.394 0.500 0.500
anova(Model.Cat)
## Analysis of Variance Table
## Df Sum Sq Mean Sq F value
## as.factor(Month) 3 552 184 3.0269
Here we show selected outcomes from the model fit.
# Estimated coefficients (recall that was random) and slope (recall that was only fixed).
coef(Model.Cat)
## $ID
## (Intercept) as.factor(Month)36 as.factor(Month)42 as.factor(Month)48
## 1 103.89905 4 7 9
## 2 113.78865 4 7 9
## 3 99.40378 4 7 9
## 4 86.81703 4 7 9
## 5 114.68770 4 7 9
## 6 96.70662 4 7 9
## 7 120.08203 4 7 9
## 8 93.11041 4 7 9
## 9 90.41324 4 7 9
## 10 96.70662 4 7 9
## 11 103.89905 4 7 9
## 12 116.48581 4 7 9
##
## attr(,"class")
## [1] "coef.mer"
# Random effects (recall these are deviations from the fixed effect, of only intercept here).
ranef(Model.Cat)
## $ID
## (Intercept)
## 1 0.8990539
## 2 10.7886474
## 3 -3.5962158
## 4 -16.1829711
## 5 11.6877013
## 6 -6.2933776
## 7 17.0820250
## 8 -9.8895934
## 9 -12.5867553
## 10 -6.2933776
## 11 0.8990539
## 12 13.4858092
# Predicted values.
predict(Model.Cat)
## 1 2 3 4 5 6 7
## 103.89905 107.89905 110.89905 112.89905 113.78865 117.78865 120.78865
## 8 9 10 11 12 13 14
## 122.78865 99.40378 103.40378 106.40378 108.40378 86.81703 90.81703
## 15 16 17 18 19 20 21
## 93.81703 95.81703 114.68770 118.68770 121.68770 123.68770 96.70662
## 22 23 24 25 26 27 28
## 100.70662 103.70662 105.70662 120.08203 124.08203 127.08203 129.08203
## 29 30 31 32 33 34 35
## 93.11041 97.11041 100.11041 102.11041 90.41324 94.41324 97.41324
## 36 37 38 39 40 41 42
## 99.41324 96.70662 100.70662 103.70662 105.70662 103.89905 107.89905
## 43 44 45 46 47 48
## 110.89905 112.89905 116.48581 120.48581 123.48581 125.48581
# Outputs the data used in the model fit. This is useful for more complicated models with missing data.
model.frame(Model.Cat)
## Values as.factor(Month) ID
## 1 108 30 1
## 2 96 36 1
## 3 110 42 1
## 4 122 48 1
## 5 103 30 2
## 6 117 36 2
## 7 127 42 2
## 8 133 48 2
## 9 96 30 3
## 10 107 36 3
## 11 106 42 3
## 12 107 48 3
## 13 84 30 4
## 14 85 36 4
## 15 92 42 4
## 16 99 48 4
## 17 118 30 5
## 18 125 36 5
## 19 125 42 5
## 20 116 48 5
## 21 110 30 6
## 22 107 36 6
## 23 96 42 6
## 24 91 48 6
## 25 129 30 7
## 26 128 36 7
## 27 123 42 7
## 28 128 48 7
## 29 90 30 8
## 30 84 36 8
## 31 101 42 8
## 32 113 48 8
## 33 84 30 9
## 34 104 36 9
## 35 100 42 9
## 36 88 48 9
## 37 96 30 10
## 38 100 36 10
## 39 103 42 10
## 40 105 48 10
## 41 105 30 11
## 42 114 36 11
## 43 105 42 11
## 44 112 48 11
## 45 113 30 12
## 46 117 36 12
## 47 132 42 12
## 48 130 48 12
Here we combine the data used and the predicted values into Data.and.Predicted
Data.and.Predicted.Cat <- cbind(model.frame(Model.Cat), Predicted=predict(Model.Cat))
# Here we modify how lmer() has named month, due to how it is treated as a factor.
names(Data.and.Predicted.Cat)
## [1] "Values" "as.factor(Month)" "ID"
## [4] "Predicted"
names(Data.and.Predicted.Cat)[2] <- "Month"
# Here we turn month (back) into a numeric representation of what, in this model, was treated categorically.
Data.and.Predicted.Cat$Month <- as.numeric(Data.and.Predicted.Cat$Month)
Now, like before, we use vit(). However, we can plot the predicted outcomes.
vit(id = "ID", occasion = "Month", score = "Predicted",
pch="", Data = Data.and.Predicted.Cat)
Random intercept only model with no effect of time.
Model.Int.Only <- lmer(Values ~ 1 + (1|ID), data=data)
summary(Model.Int.Only)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ 1 + (1 | ID)
## Data: data
##
## REML criterion at convergence: 361.1
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.8488 -0.6912 0.1359 0.6088 1.7441
##
## Random effects:
## Groups Name Variance Std.Dev.
## ID (Intercept) 132.78 11.523
## Residual 71.06 8.429
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 108.000 3.542 30.49
Data.and.Predicted.Int.Only <- cbind(Month=data$Month, model.frame(Model.Int.Only), Predicted=predict(Model.Int.Only))
vit(id = "ID", occasion = "Month", score = "Predicted", pch="", Data = Data.and.Predicted.Int.Only)
Here, for the above model, we can view the mean of the values and the prediction. Note that the predicted values for this model have a standard deviation of zero, as it is a means only model.
Data.and.Predicted.Int.Only %>%
group_by(ID) %>%
summarize(
Mean.Values = mean(Values),
S.Values = sd(Values),
Mean.Predicted = mean(Predicted),
S.Predicted = sd(Predicted))
## # A tibble: 12 × 5
## ID Mean.Values S.Values Mean.Predicted S.Predicted
## <int> <dbl> <dbl> <dbl> <dbl>
## 1 1 109 10.645813 108.88200 0
## 2 2 120 13.114877 118.58404 0
## 3 3 104 5.354126 104.47199 0
## 4 4 90 6.976150 92.12394 0
## 5 5 121 4.690416 119.46604 0
## 6 6 101 8.981462 101.82598 0
## 7 7 127 2.708013 124.75806 0
## 8 8 97 12.780193 98.29797 0
## 9 9 94 9.521905 95.65196 0
## 10 10 101 3.915780 101.82598 0
## 11 11 109 4.690416 108.88200 0
## 12 12 123 9.416298 121.23005 0
Compare the models using anova()
anova(Model.Int.Only, Model.Cat)
## refitting model(s) with ML (instead of REML)
## Data: data
## Models:
## Model.Int.Only: Values ~ 1 + (1 | ID)
## Model.Cat: Values ~ as.factor(Month) + (1 | ID)
## Df AIC BIC logLik deviance Chisq Chi Df Pr(>Chisq)
## Model.Int.Only 3 371.47 377.08 -182.73 365.47
## Model.Cat 6 368.71 379.94 -178.36 356.71 8.751 3 0.03279 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
We begin by treating Month as a factor for the fixed effects but as a continuous value for the random effect. Compare this to Table 15.3 in MDK (see especially the F-value from anova()).
Model.0 <- lmer(Values ~ as.factor(Month) + (1 + Month|ID), data=data)
summary(Model.0)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ as.factor(Month) + (1 + Month | ID)
## Data: data
##
## REML criterion at convergence: 336.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.81430 -0.47911 -0.05763 0.57397 1.53583
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## ID (Intercept) 712.8192 26.6987
## Month 0.3892 0.6239 -0.90
## Residual 37.4364 6.1185
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 103.000 4.138 24.892
## as.factor(Month)36 4.000 2.722 1.470
## as.factor(Month)42 7.000 3.303 2.119
## as.factor(Month)48 9.000 4.092 2.199
##
## Correlation of Fixed Effects:
## (Intr) a.(M)3 a.(M)42
## as.fct(M)36 -0.421
## as.fct(M)42 -0.465 0.607
## as.fct(M)48 -0.471 0.595 0.749
anova(Model.0)
## Analysis of Variance Table
## Df Sum Sq Mean Sq F value
## as.factor(Month) 3 200.07 66.689 1.7814
Now, we plot the predicted scores with “Model.0,” which considers the fixed effect of month but a random slope for month.
Data.and.Predicted.0 <- cbind(model.frame(Model.0), Predicted=predict(Model.0))
vit(id = "ID", occasion = "Month", score = "Predicted", pch="", Data = Data.and.Predicted.0)
Here a model with fixed effects for linear, quadratic, and cubic effects are included, along with random effects for intercept and the linear effect.
Model.Trends <- lmer(Values ~ Month + I(Month^2) + I(Month^3) + (1+Month|ID), data=data)
## Warning: Some predictor variables are on very different scales: consider
## rescaling
summary(Model.Trends)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ Month + I(Month^2) + I(Month^3) + (1 + Month | ID)
## Data: data
##
## REML criterion at convergence: 362.8
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.81429 -0.47911 -0.05762 0.57397 1.53581
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## ID (Intercept) 712.7799 26.6979
## Month 0.3892 0.6238 -0.90
## Residual 37.4370 6.1186
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 6.800e+01 3.460e+02 0.197
## Month 1.583e+00 2.743e+01 0.058
## I(Month^2) -1.389e-02 7.135e-01 -0.019
## I(Month^3) 3.527e-13 6.095e-03 0.000
##
## Correlation of Fixed Effects:
## (Intr) Month I(M^2)
## Month -0.999
## I(Month^2) 0.997 -0.999
## I(Month^3) -0.994 0.998 -0.999
## fit warnings:
## Some predictor variables are on very different scales: consider rescaling
Now we treat Month is treated as a quantitative variable in the straight-line change model formulation. Notice here that the covariance parameters (i.e., the variance of the random effects) is similar to that reported in the book. By default, the lmer() function uses a variation of maximum likelihood estimation termed “restricted information maximum likelihood.” Further, the way in which SAS and the lmer() function implement the estimation procedures are diffrent.
Model <- lmer(Values ~ Month + (1|ID), data=data)
summary(Model)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ Month + (1 | ID)
## Data: data
##
## REML criterion at convergence: 354.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.99786 -0.49141 -0.03432 0.54885 1.68963
##
## Random effects:
## Groups Name Variance Std.Dev.
## ID (Intercept) 136.13 11.668
## Residual 57.66 7.593
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 88.5000 7.2901 12.14
## Month 0.5000 0.1634 3.06
##
## Correlation of Fixed Effects:
## (Intr)
## Month -0.874
Notice that the above output does not equal what is displayed in the book, as the intercept there is 103.5 but 88.5 here. Recall the interpretation of the intercept. This is due to the scaling of time. Here we will create a new time variable that simply subtracts the minimum value of time from all time values so that the intercept represents the mean at the initial timepoint.
data$Months.from.30 <- data$Month - 30
Model.30 <- lmer(Values ~ Months.from.30 + (1|ID), data=data)
summary(Model.30)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ Months.from.30 + (1 | ID)
## Data: data
##
## REML criterion at convergence: 354.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.99786 -0.49141 -0.03432 0.54885 1.68963
##
## Random effects:
## Groups Name Variance Std.Dev.
## ID (Intercept) 136.13 11.668
## Residual 57.66 7.593
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 103.5000 3.8350 26.99
## Months.from.30 0.5000 0.1634 3.06
##
## Correlation of Fixed Effects:
## (Intr)
## Mnths.fr.30 -0.383
We can use “full information maximum likelihood” with REML=FALSE
Model.30_ML <- lmer(Values ~ Months.from.30 + (1|ID), REML=FALSE, data=data)
summary(Model.30_ML)
## Linear mixed model fit by maximum likelihood ['lmerMod']
## Formula: Values ~ Months.from.30 + (1 | ID)
## Data: data
##
## AIC BIC logLik deviance df.resid
## 364.9 372.4 -178.5 356.9 44
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -2.03163 -0.49276 -0.03287 0.55799 1.70818
##
## Random effects:
## Groups Name Variance Std.Dev.
## ID (Intercept) 123.99 11.135
## Residual 56.06 7.487
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 103.5000 3.6881 28.063
## Months.from.30 0.5000 0.1611 3.104
##
## Correlation of Fixed Effects:
## (Intr)
## Mnths.fr.30 -0.393
Here we show selected outcomes from the model fit using full information maximum likelihood.
# Estimated coefficients (recall that was random) and slope (recall that was only fixed).
coef(Model.30_ML)
## $ID
## (Intercept) Months.from.30
## 1 104.39845 0.5
## 2 114.28140 0.5
## 3 99.90620 0.5
## 4 87.32790 0.5
## 5 115.17985 0.5
## 6 97.21085 0.5
## 7 120.57055 0.5
## 8 93.61705 0.5
## 9 90.92170 0.5
## 10 97.21085 0.5
## 11 104.39845 0.5
## 12 116.97675 0.5
##
## attr(,"class")
## [1] "coef.mer"
# Random effects (recall these are deviations from the fixed effect, of only intercept here).
ranef(Model.30_ML)
## $ID
## (Intercept)
## 1 0.8984501
## 2 10.7814010
## 3 -3.5938003
## 4 -16.1721015
## 5 11.6798511
## 6 -6.2891506
## 7 17.0705516
## 8 -9.8829509
## 9 -12.5783012
## 10 -6.2891506
## 11 0.8984501
## 12 13.4767513
# Predicted values.
predict(Model.30_ML)
## 1 2 3 4 5 6 7
## 104.39845 107.39845 110.39845 113.39845 114.28140 117.28140 120.28140
## 8 9 10 11 12 13 14
## 123.28140 99.90620 102.90620 105.90620 108.90620 87.32790 90.32790
## 15 16 17 18 19 20 21
## 93.32790 96.32790 115.17985 118.17985 121.17985 124.17985 97.21085
## 22 23 24 25 26 27 28
## 100.21085 103.21085 106.21085 120.57055 123.57055 126.57055 129.57055
## 29 30 31 32 33 34 35
## 93.61705 96.61705 99.61705 102.61705 90.92170 93.92170 96.92170
## 36 37 38 39 40 41 42
## 99.92170 97.21085 100.21085 103.21085 106.21085 104.39845 107.39845
## 43 44 45 46 47 48
## 110.39845 113.39845 116.97675 119.97675 122.97675 125.97675
# Outputs the data used in the model fit. This is useful for more complicated models with missing data.
model.frame(Model.30_ML)
## Values Months.from.30 ID
## 1 108 0 1
## 2 96 6 1
## 3 110 12 1
## 4 122 18 1
## 5 103 0 2
## 6 117 6 2
## 7 127 12 2
## 8 133 18 2
## 9 96 0 3
## 10 107 6 3
## 11 106 12 3
## 12 107 18 3
## 13 84 0 4
## 14 85 6 4
## 15 92 12 4
## 16 99 18 4
## 17 118 0 5
## 18 125 6 5
## 19 125 12 5
## 20 116 18 5
## 21 110 0 6
## 22 107 6 6
## 23 96 12 6
## 24 91 18 6
## 25 129 0 7
## 26 128 6 7
## 27 123 12 7
## 28 128 18 7
## 29 90 0 8
## 30 84 6 8
## 31 101 12 8
## 32 113 18 8
## 33 84 0 9
## 34 104 6 9
## 35 100 12 9
## 36 88 18 9
## 37 96 0 10
## 38 100 6 10
## 39 103 12 10
## 40 105 18 10
## 41 105 0 11
## 42 114 6 11
## 43 105 12 11
## 44 112 18 11
## 45 113 0 12
## 46 117 6 12
## 47 132 12 12
## 48 130 18 12
Here we combine the data used and the predicted values into Data.and.Predicted
Data.and.Predicted <- cbind(model.frame(Model.30_ML), Predicted=predict(Model.30_ML))
Now, like before, we use vit(). However, we can plot the predicted outcomes.
vit(id = "ID", occasion = "Months.from.30", score = "Predicted", pch="", Data = Data.and.Predicted, xlab="Number of Months From Baseline")
Now we fit a model in which there is a random intercept and a random linear trend (notice the parenthetical term within the lmer() function now has 1+Month). Note that this model treats Month as a numeric variable, whereas the output from Table 15.4 in MDK treats time as a categorical variable for the fixed effects but quantitatively for the random effects. Compare this output to Table 15.6 in MDK.
Model.Linear <- lmer(Values ~ Month + (1 + Month|ID), data=data)
summary(Model.Linear)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ Month + (1 + Month | ID)
## Data: data
##
## REML criterion at convergence: 349.1
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.79182 -0.43847 0.00418 0.64190 1.68326
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## ID (Intercept) 735.5977 27.1219
## Month 0.4037 0.6354 -0.90
## Residual 34.8169 5.9006
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 88.5000 9.3028 9.513
## Month 0.5000 0.2231 2.241
##
## Correlation of Fixed Effects:
## (Intr)
## Month -0.925
anova(Model.Linear)
## Analysis of Variance Table
## Df Sum Sq Mean Sq F value
## Month 1 174.91 174.91 5.0237
Here we combine the data used and the predicted values into Data.and.Predicted
Data.and.Predicted.Linear <- cbind(model.frame(Model.Linear), Predicted=predict(Model.Linear))
As before, we use use vit(). There are now individual differences in both the intercepts and slopes.
vit(id = "ID", occasion = "Month", score = "Predicted", pch="", Data = Data.and.Predicted.Linear)
Now we fit a model in which there are fixed effects for the intercept and each month (i.e., month is treated categorically) and a random intercept and linear trend. Importantly, note that this model treats Month as a categorical variable for the fixed effect and as a numeric variable for the random effect. This model maps onto Table 15.4 in MDK.
Model.Categorical.Fix_Linear.Random <- lmer(Values ~ as.factor(Month) + (1 + Month|ID), data=data)
summary(Model.Categorical.Fix_Linear.Random)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ as.factor(Month) + (1 + Month | ID)
## Data: data
##
## REML criterion at convergence: 336.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.81430 -0.47911 -0.05763 0.57397 1.53583
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## ID (Intercept) 712.8192 26.6987
## Month 0.3892 0.6239 -0.90
## Residual 37.4364 6.1185
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 103.000 4.138 24.892
## as.factor(Month)36 4.000 2.722 1.470
## as.factor(Month)42 7.000 3.303 2.119
## as.factor(Month)48 9.000 4.092 2.199
##
## Correlation of Fixed Effects:
## (Intr) a.(M)3 a.(M)42
## as.fct(M)36 -0.421
## as.fct(M)42 -0.465 0.607
## as.fct(M)48 -0.471 0.595 0.749
anova(Model.Categorical.Fix_Linear.Random)
## Analysis of Variance Table
## Df Sum Sq Mean Sq F value
## as.factor(Month) 3 200.07 66.689 1.7814
Here we create a Month variable that is treated as a factor (thus, using this variable make it unnecessary to use as.factor(Month)).
data2 <- cbind(data, Month_Factor=as.factor(data$Month))
# Using str() we can see the structure of each variable.
str(data2)
## 'data.frame': 48 obs. of 5 variables:
## $ ID : int 1 1 1 1 2 2 2 2 3 3 ...
## $ Month : num 30 36 42 48 30 36 42 48 30 36 ...
## $ Values : int 108 96 110 122 103 117 127 133 96 107 ...
## $ Months.from.30: num 0 6 12 18 0 6 12 18 0 6 ...
## $ Month_Factor : Factor w/ 4 levels "30","36","42",..: 1 2 3 4 1 2 3 4 1 2 ...
Notice that data2 is now being used, as it include a variable for Month treated categorically (for fixed effect) as well as quantitatively (for random effect). These results map onto the first part of Table 15.5 (with summary()) and then the second part (with anova()). Finally, confidence intervals are given using the `confint’ function.
Model.Categorical.Fix_Linear.Random <- lmer(Values ~ Month_Factor + (1 + Month|ID), data=data2)
summary(Model.Categorical.Fix_Linear.Random)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ Month_Factor + (1 + Month | ID)
## Data: data2
##
## REML criterion at convergence: 336.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.81430 -0.47911 -0.05763 0.57397 1.53583
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## ID (Intercept) 712.8192 26.6987
## Month 0.3892 0.6239 -0.90
## Residual 37.4364 6.1185
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 103.000 4.138 24.892
## Month_Factor36 4.000 2.722 1.470
## Month_Factor42 7.000 3.303 2.119
## Month_Factor48 9.000 4.092 2.199
##
## Correlation of Fixed Effects:
## (Intr) Mn_F36 Mn_F42
## Mnth_Fctr36 -0.421
## Mnth_Fctr42 -0.465 0.607
## Mnth_Fctr48 -0.471 0.595 0.749
anova(Model.Categorical.Fix_Linear.Random)
## Analysis of Variance Table
## Df Sum Sq Mean Sq F value
## Month_Factor 3 200.07 66.689 1.7814
CIs <- confint(Model.Categorical.Fix_Linear.Random)
## Computing profile confidence intervals ...
CIs
## 2.5 % 97.5 %
## .sig01 25.5395248 25.694276
## .sig02 -0.9742166 -0.271004
## .sig03 0.1888073 1.091053
## .sigma 4.5233976 8.005324
## (Intercept) 94.6324000 111.367601
## Month_Factor36 -1.2524813 9.252481
## Month_Factor42 0.5367615 13.463239
## Month_Factor48 0.7050039 17.294997
Here we combine the data used and the predicted values into Data.and.Predicted. This figure maps onto Figure 15.5.
Data.and.Predicted.Linear_CFLR <- cbind(model.frame(Model.Categorical.Fix_Linear.Random),
Predicted=predict(Model.Categorical.Fix_Linear.Random))
vit(id = "ID", occasion = "Month", score = "Predicted", pch="",
Data = Data.and.Predicted.Linear_CFLR)
Here we fit a straight-line change model with random intercept and slope. This maps onto the first part of Table 15.6 (with summary()) and then the second part (with anova())
Model.SLCM <- lmer(Values ~ Month + (1 + Month|ID), data=data)
summary(Model.SLCM)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ Month + (1 + Month | ID)
## Data: data
##
## REML criterion at convergence: 349.1
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.79182 -0.43847 0.00418 0.64190 1.68326
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## ID (Intercept) 735.5977 27.1219
## Month 0.4037 0.6354 -0.90
## Residual 34.8169 5.9006
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 88.5000 9.3028 9.513
## Month 0.5000 0.2231 2.241
##
## Correlation of Fixed Effects:
## (Intr)
## Month -0.925
anova(Model.SLCM)
## Analysis of Variance Table
## Df Sum Sq Mean Sq F value
## Month 1 174.91 174.91 5.0237
We can very explicetely create categorical variables for the months (to illustrate a more step-by-step approach).
data2$Month30 <- as.numeric(data2$Month==30)
data2$Month36 <- as.numeric(data2$Month==36)
data2$Month42 <- as.numeric(data2$Month==42)
data2$Month48 <- as.numeric(data2$Month==48)
Compare the output below to the SAS output (which uses a different reference group) in Table 15.4 of MDK.
Model.Categorical.Fix_Linear.Random_Categorical <- lmer(Values ~ Month30 + Month36 + Month42 +
(1 + Month|ID), data=data2)
summary(Model.Categorical.Fix_Linear.Random_Categorical)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ Month30 + Month36 + Month42 + (1 + Month | ID)
## Data: data2
##
## REML criterion at convergence: 336.4
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.81430 -0.47911 -0.05762 0.57397 1.53582
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## ID (Intercept) 712.8091 26.6985
## Month 0.3892 0.6238 -0.90
## Residual 37.4365 6.1185
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 112.000 4.231 26.470
## Month30 -9.000 4.092 -2.199
## Month36 -5.000 3.303 -1.514
## Month42 -2.000 2.722 -0.735
##
## Correlation of Fixed Effects:
## (Intr) Mnth30 Mnth36
## Month30 -0.506
## Month36 -0.493 0.749
## Month42 -0.434 0.595 0.607
anova(Model.Categorical.Fix_Linear.Random_Categorical)
## Analysis of Variance Table
## Df Sum Sq Mean Sq F value
## Month30 1 112.283 112.283 2.9993
## Month36 1 67.571 67.571 1.8049
## Month42 1 20.217 20.217 0.5400
# Using Month continuously; random intercept and slope.
No.Random_Con <- lmer(Values ~ Month + (1+Month|ID), data=data2)
summary(No.Random_Con)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ Month + (1 + Month | ID)
## Data: data2
##
## REML criterion at convergence: 349.1
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.79182 -0.43847 0.00418 0.64190 1.68326
##
## Random effects:
## Groups Name Variance Std.Dev. Corr
## ID (Intercept) 735.5977 27.1219
## Month 0.4037 0.6354 -0.90
## Residual 34.8169 5.9006
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 88.5000 9.3028 9.513
## Month 0.5000 0.2231 2.241
##
## Correlation of Fixed Effects:
## (Intr)
## Month -0.925
anova(No.Random_Con)
## Analysis of Variance Table
## Df Sum Sq Mean Sq F value
## Month 1 174.91 174.91 5.0237
# Using the Months categorically; random intercept only.
No.Random_Cat <- lmer(Values ~ Month30 + Month36 + Month42 + (1|ID), data=data2)
summary(No.Random_Cat)
## Linear mixed model fit by REML ['lmerMod']
## Formula: Values ~ Month30 + Month36 + Month42 + (1 | ID)
## Data: data2
##
## REML criterion at convergence: 340.8
##
## Scaled residuals:
## Min 1Q Median 3Q Max
## -1.88627 -0.44709 -0.09063 0.53924 1.70501
##
## Random effects:
## Groups Name Variance Std.Dev.
## ID (Intercept) 135.35 11.634
## Residual 60.79 7.797
## Number of obs: 48, groups: ID, 12
##
## Fixed effects:
## Estimate Std. Error t value
## (Intercept) 112.000 4.043 27.703
## Month30 -9.000 3.183 -2.828
## Month36 -5.000 3.183 -1.571
## Month42 -2.000 3.183 -0.628
##
## Correlation of Fixed Effects:
## (Intr) Mnth30 Mnth36
## Month30 -0.394
## Month36 -0.394 0.500
## Month42 -0.394 0.500 0.500
anova(No.Random_Cat)
## Analysis of Variance Table
## Df Sum Sq Mean Sq F value
## Month30 1 400 400 6.5803
## Month36 1 128 128 2.1057
## Month42 1 24 24 0.3948
The nlme package predates the lmer package and hasdifferent capabilities. The “nl” part of nlme is “nonlinear.” Thus, models that cannot be written as a linear function (e.g., of time) can often be fit using nlme. However, there are other benefits and capabilities in nlme, such as the generalized least squares function, which is for fitting linear models using generalized least squares. As noted in the helpful for gls(): “the errors are allowed to be correlated and/or have unequal variances.” With some of the alternative models discussed in MDK, the gls() function can be used. Interestingly, as the gls() model is not exactly a mixed effects model, it is included in a mixed-effects modeling package (i.e., nlme but also SAS PROC MIXED) in much the same way such models are included in the mixed-effects modeling section part of MDK (recall we discuss how it can be considered a special case of such models).
# install.packages("nlme")
library(nlme)
##
## Attaching package: 'nlme'
## The following object is masked from 'package:lme4':
##
## lmList
## The following object is masked from 'package:dplyr':
##
## collapse
Here the variance is estimated differently for each month (which is considered here a factor) using the weights parameter and the varIdent() function. In words, the one-sided formula says that the variance is allowed to differ for each value of month. Thus, there is not homogeneity of variance across months assumed with the model below.
Model.GLS.1 <- gls(Values ~ Month_Factor,
weights = varIdent(form = ~ 1 | Month_Factor), data = data2)
summary(Model.GLS.1)
## Generalized least squares fit by REML
## Model: Values ~ Month_Factor
## Data: data2
## AIC BIC logLik
## 382.9476 397.2211 -183.4738
##
## Variance function:
## Structure: Different standard deviations per stratum
## Formula: ~1 | Month_Factor
## Parameter estimates:
## 30 36 42 48
## 1.0000000 1.0328266 0.9730408 1.0768354
##
## Coefficients:
## Value Std.Error t-value p-value
## (Intercept) 103 3.958114 26.022493 0.0000
## Month_Factor36 4 5.690236 0.702959 0.4858
## Month_Factor42 7 5.522681 1.267500 0.2116
## Month_Factor48 9 5.816643 1.547284 0.1290
##
## Correlation:
## (Intr) Mn_F36 Mn_F42
## Month_Factor36 -0.696
## Month_Factor42 -0.717 0.499
## Month_Factor48 -0.680 0.473 0.488
##
## Standardized residuals:
## Min Q1 Med Q3 Max
## -1.6254850 -0.6933168 0.0000000 0.7119397 1.8962448
##
## Residual standard error: 13.71131
## Degrees of freedom: 48 total; 44 residual
anova(Model.GLS.1)
## Denom. DF: 44
## numDF F-value p-value
## (Intercept) 1 2865.6639 <.0001
## Month_Factor 3 0.9345 0.4321
Other information is available within the object Model.GLS.1. The specific objects within Model.GLS.1 can be identified with names().
names(Model.GLS.1)
## [1] "modelStruct" "dims" "contrasts" "coefficients"
## [5] "varBeta" "sigma" "apVar" "logLik"
## [9] "numIter" "groups" "call" "method"
## [13] "fitted" "residuals" "parAssign" "na.action"
In addition to the heterogenious variances across the months, we can allow a correlational structure by including the correlation parameter in gls() information is available within the object Model.GLS.1. The specific objects within Model.GLS.1 can be identified with names(). Ths “1 | ID” part of the code says, in words, that “the errors are allowed to correlate.” Thus, combining weights = varIdent(form = ~ 1 | Month_Factor) and correlation=corSymm(form = ~ 1 | ID) in a gls() call leads to an unstructured covariance matrix for the errors. Compare these results to Table 15.10 in MDK. Note that the correlational structure part of the output corresponds to the “estimated correlation matrix for Subject 1” at the bottom of Table 15.10. Further, note that the anova() function produces output that corresponds to the “Type 3 Tests of Fixed Effects” in Table 15.10 (though the \(p\)-values differ because of some differences in operationalization of certain ideas in SAS PROC MIXED as compared to nlme).
Model.GLS <- gls(Values ~ Month_Factor,
weights = varIdent(form = ~ 1 | Month_Factor),
correlation=corSymm(form = ~ 1 | ID),
data = data2)
summary(Model.GLS)
## Generalized least squares fit by REML
## Model: Values ~ Month_Factor
## Data: data2
## AIC BIC logLik
## 353.1128 378.0915 -162.5564
##
## Correlation Structure: General
## Formula: ~1 | ID
## Parameter estimate(s):
## Correlation:
## 1 2 3
## 2 0.795
## 3 0.696 0.760
## 4 0.599 0.466 0.853
## Variance function:
## Structure: Different standard deviations per stratum
## Formula: ~1 | Month_Factor
## Parameter estimates:
## 30 36 42 48
## 1.000000 1.032823 0.973040 1.076839
##
## Coefficients:
## Value Std.Error t-value p-value
## (Intercept) 103 3.958101 26.022581 0.0000
## Month_Factor36 4 2.579053 1.550957 0.1281
## Month_Factor42 7 3.045127 2.298755 0.0263
## Month_Factor48 9 3.692759 2.437202 0.0189
##
## Correlation:
## (Intr) Mn_F36 Mn_F42
## Month_Factor36 -0.275
## Month_Factor42 -0.419 0.530
## Month_Factor48 -0.381 0.087 0.797
##
## Standardized residuals:
## Min Q1 Med Q3 Max
## -1.625485e+00 -6.933197e-01 1.965979e-15 7.119438e-01 1.896251e+00
##
## Residual standard error: 13.71126
## Degrees of freedom: 48 total; 44 residual
anova(Model.GLS)
## Denom. DF: 44
## numDF F-value p-value
## (Intercept) 1 934.3057 <.0001
## Month_Factor 3 2.7379 0.0547
There are auxilary functions that can be useful. One such function is the getVarCov() function, which extracts the covariance matrix for the errors. See Table 15.8 in MDK.
getVarCov(Model.GLS)
## Marginal variance covariance matrix
## [,1] [,2] [,3] [,4]
## [1,] 188.00 154.360 127.36 121.180
## [2,] 154.36 200.540 143.63 97.452
## [3,] 127.36 143.630 178.00 168.090
## [4,] 121.18 97.452 168.09 218.000
## Standard Deviations: 13.711 14.161 13.342 14.765
The cov2cor() function can be used for turning the extracted covariance matrix into the correlation matrix. See Table 15.9 in MDK.
cov2cor(getVarCov(Model.GLS))
## Marginal variance covariance matrix
## [,1] [,2] [,3] [,4]
## [1,] 1.00000 0.79498 0.69623 0.59859
## [2,] 0.79498 1.00000 0.76023 0.46608
## [3,] 0.69623 0.76023 1.00000 0.85331
## [4,] 0.59859 0.46608 0.85331 1.00000
## Standard Deviations: 1 1 1 1
As discussed in the book, there are yet other correlational structures for the errors that can be used. Here we show a structure that is called compound symmetry (equal covariances and equal variances). See Table 15.11 in MDK. Notice that the corCompSymm() function is used, which specifies that compound symmetry be used. Note too that the weights parameter is not needed as above (as the variances are the same for each month).
Model.GLS.CS <- gls(Values ~ Month_Factor,
correlation=corCompSymm(form = ~ 1 | ID),
data = data2)
summary(Model.GLS.CS)
## Generalized least squares fit by REML
## Model: Values ~ Month_Factor
## Data: data2
## AIC BIC logLik
## 352.7563 363.4614 -170.3781
##
## Correlation Structure: Compound symmetry
## Formula: ~1 | ID
## Parameter estimate(s):
## Rho
## 0.6900734
##
## Coefficients:
## Value Std.Error t-value p-value
## (Intercept) 103 4.042858 25.477030 0.0000
## Month_Factor36 4 3.182972 1.256687 0.2155
## Month_Factor42 7 3.182972 2.199202 0.0332
## Month_Factor48 9 3.182972 2.827546 0.0070
##
## Correlation:
## (Intr) Mn_F36 Mn_F42
## Month_Factor36 -0.394
## Month_Factor42 -0.394 0.500
## Month_Factor48 -0.394 0.500 0.500
##
## Standardized residuals:
## Min Q1 Med Q3 Max
## -1.713690e+00 -6.604846e-01 2.029416e-15 7.140374e-01 1.856497e+00
##
## Residual standard error: 14.00487
## Degrees of freedom: 48 total; 44 residual
anova(Model.GLS.CS)
## Denom. DF: 44
## numDF F-value p-value
## (Intercept) 1 929.7391 <.0001
## Month_Factor 3 3.0269 0.0394
getVarCov(Model.GLS.CS)
## Marginal variance covariance matrix
## [,1] [,2] [,3] [,4]
## [1,] 196.14 135.35 135.35 135.35
## [2,] 135.35 196.14 135.35 135.35
## [3,] 135.35 135.35 196.14 135.35
## [4,] 135.35 135.35 135.35 196.14
## Standard Deviations: 14.005 14.005 14.005 14.005
Another structure that may be of interest is an autoregressive structure, which can be implemented with the corAR1() function. Compare these results with Table 15.12. More generally, for other predefined correlational structures, see the corClasses() function from the nlme package.
Model.GLS.AR <- gls(Values ~ Month_Factor,
correlation=corAR1(form = ~ 1 | ID),
data = data2)
summary(Model.GLS.AR)
## Generalized least squares fit by REML
## Model: Values ~ Month_Factor
## Data: data2
## AIC BIC logLik
## 345.1387 355.8438 -166.5693
##
## Correlation Structure: AR(1)
## Formula: ~1 | ID
## Parameter estimate(s):
## Phi
## 0.8064014
##
## Coefficients:
## Value Std.Error t-value p-value
## (Intercept) 103 4.076796 25.264938 0.0000
## Month_Factor36 4 2.536793 1.576794 0.1220
## Month_Factor42 7 3.409512 2.053080 0.0460
## Month_Factor48 9 3.976123 2.263512 0.0286
##
## Correlation:
## (Intr) Mn_F36 Mn_F42
## Month_Factor36 -0.311
## Month_Factor42 -0.418 0.672
## Month_Factor48 -0.488 0.526 0.774
##
## Standardized residuals:
## Min Q1 Med Q3 Max
## -1.699424e+00 -6.549862e-01 -2.012522e-15 7.080931e-01 1.841042e+00
##
## Residual standard error: 14.12244
## Degrees of freedom: 48 total; 44 residual
anova(Model.GLS.AR)
## Denom. DF: 44
## numDF F-value p-value
## (Intercept) 1 921.6425 <.0001
## Month_Factor 3 1.8041 0.1604
getVarCov(Model.GLS.AR)
## Marginal variance covariance matrix
## [,1] [,2] [,3] [,4]
## [1,] 199.44 160.83 129.69 104.59
## [2,] 160.83 199.44 160.83 129.69
## [3,] 129.69 160.83 199.44 160.83
## [4,] 104.59 129.69 160.83 199.44
## Standard Deviations: 14.122 14.122 14.122 14.122