Split-plot 1: How does a linear mixed model look like?

I like statistics and I struggle with statistics. Often times I get frustrated when I don’t understand and I really struggled to make sense of Krushke’s Bayesian analysis of a split-plot, particularly because ‘it didn’t look like’ a split-plot to me.

Additionally, I have made a few posts discussing linear mixed models using several different packages to fit them. At no point I have shown what are the calculations behind the scenes. So, I decided to combine my frustration and an explanation to myself in a couple of posts. This is number one and the follow up is Split-plot 2: let’s throw in some spatial effects.

Example of forestry split-plot: one of my colleagues has a trial in which stocking (number of trees per ha) is the main plot and fertilization is the subplot (higher stockings look darker because trees are closer together).

The previous model equation still requires some assumptions about the distribution of the random effects. A very common set of assumptions is to say that the residuals are iid (identical and independently distributed) normal (so \( \boldsymbol{R} = \sigma^2_e \boldsymbol{I} \)) and that the random effects are independent of each other, so \( \boldsymbol{G} = \boldsymbol{B} \bigoplus \boldsymbol{M}\) is a direct sum of the variance of blocks (\( \boldsymbol{B} = \sigma^2_B \boldsymbol{I}\)) and main plots (\( \boldsymbol{M} = \sigma^2_M \boldsymbol{I}\)).

An interesting feature of this matrix formulation is that we can express all sort of models by choosing different assumptions for our covariance matrices (using different covariance structures). Do you have longitudinal data (units assessed repeated times)? Is there spatial correlation? Account for this in the \( \boldsymbol{R}\) matrix. Random effects are correlated (e.g. maternal and additive genetic effects in genetics)? Account for this in the \( \boldsymbol{G}\) matrix. Multivariate response? Deal with unstructured \( \boldsymbol{R}\) and \( \boldsymbol{G}\), or model the correlation structure using different constraints (and the you’ll need asreml).

By the way, the history of linear mixed models is strongly related to applications of quantitative genetics for the prediction of breeding values, particularly in dairy cattle. Charles Henderson developed what is now called Henderson’s Mixed Model Equations† to simultaneously estimate fixed effects and predict random genetic effects:

The big matrix on the left-hand side of this equation is often called the \( \boldsymbol{C} \) matrix. You could be thinking ‘What does this all mean?’ It is easier to see what is going on with a small example, but rather than starting with, say, a complete block design, we’ll go for a split-plot to start tackling my annoyance with the aforementioned blog post.

Old school: physical split-plots

Given that I’m an unsophisticated forester and that I’d like to use data available to anyone, I’ll rely on an agricultural example (so plots are actually physical plots in the field) that goes back to Frank Yates. There are two factors (oats variety, with three levels, and fertilization, with four levels). Yates, F. (1935) Complex experiments, Journal of the Royal Statistical Society Suppl. 2, 181–247 (behind pay wall here).

Layout of oats experiment in Yates’s paper, from a time when articles were meaty. Each of the 6 replicates is divided in to 3 main plots for oats varieties (v1, v2 and v3), while each variety was divided into four parts with different levels of fertilization (manure—animal crap—n1 to n4). Cells display yield.

Now it is time to roll up our sleeves and use some code, getting the data and fitting the same model using nlme (m1) and asreml (m2), just for the fun of it. Anyway, nlme and asreml produce exactly the same results.

We will use the oats data set that comes with MASS, although there is also an Oats data set in nlme and another version in the asreml package. (By the way, you can see a very good explanation by Bill Venables of a ‘traditional’ ANOVA analysis for a split-plot here):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

require(MASS)# we get the oats data from here

require(nlme)# for lme function

require(asreml)# for asreml function. This dataset use different variable names,

Now we can move to implement the Mixed Model Equations, where probably the only gotcha is the definition of the \(\boldsymbol{Z}\) matrix (incidence matrix for random effects), as both nlme and asreml use ‘number of levels of the factor’ for both the main and interactions effects, which involves using the contrasts.arg argument in model.matrix().

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

# Variance components

varB=214.477

varMP=106.062

varR=177.083

# Basic vector and matrices: y, X, Z, G & R

y=matrix(oats$Y,nrow=dim(oats)[1],ncol=1)

X=model.matrix(~V*N,data=oats)

Z=model.matrix(~B/MP-1,data=oats,

contrasts.arg=list(B=contrasts(oats$B,contrasts=F),

MP=contrasts(oats$MP,contrasts=F)))

G=diag(c(rep(varB,6),rep(varMP,18)))

R=diag(varR,72,72)

Rinv=solve(R)

# Components of C

XpX=t(X)%*%Rinv%*%X

ZpZ=t(Z)%*%Rinv%*%Z

XpZ=t(X)%*%Rinv%*%Z

ZpX=t(Z)%*%Rinv%*%X

Xpy=t(X)%*%Rinv%*%y

Zpy=t(Z)%*%Rinv%*%y

# Building C * [b a] = RHS

C=rbind(cbind(XpX,XpZ),

cbind(ZpX,ZpZ+solve(G)))

RHS=rbind(Xpy,Zpy)

blup=solve(C,RHS)

blup

# [,1]

# (Intercept) 80.0000000

# VMarvellous 6.6666667

# VVictory -8.5000000

# N0.2cwt 18.5000000

# N0.4cwt 34.6666667

# N0.6cwt 44.8333333

# VMarvellous:N0.2cwt 3.3333333

# VVictory:N0.2cwt -0.3333333

# VMarvellous:N0.4cwt -4.1666667

# VVictory:N0.4cwt 4.6666667

# VMarvellous:N0.6cwt -4.6666667

# VVictory:N0.6cwt 2.1666667

# BI 25.4215578

# BII 2.6569919

# BIII -6.5298953

# BIV -4.7060280

# BV -10.5829337

# BVI -6.2596927

# BI:MPGolden.rain 2.3482656

# BII:MPGolden.rain 4.2987082

# BIII:MPGolden.rain -7.9159514

# BIV:MPGolden.rain 5.7894753

# BV:MPGolden.rain 1.1167834

# BVI:MPGolden.rain -5.6372811

# BI:MPMarvellous -3.8543865

# BII:MPMarvellous 6.2094778

# BIII:MPMarvellous 10.7507978

# BIV:MPMarvellous -7.1155687

# BV:MPMarvellous -9.8480945

# BVI:MPMarvellous 3.8577740

# BI:MPVictory 14.0774514

# BII:MPVictory -9.1942649

# BIII:MPVictory -6.0639747

# BIV:MPVictory -1.0011059

# BV:MPVictory 3.4978963

# BVI:MPVictory -1.3160021

Not surprisingly, we get the same results, except that we start assuming the variance components from the previous analyses, so we can avoid implementing the code for restricted maximum likelihood estimation as well. By the way, given that \( \boldsymbol{R}^{-1} \) is in all terms it can be factored out from the MME, leaving terms like \( \boldsymbol{X}’ \boldsymbol{X} \), i.e. without \( \boldsymbol{R}^{-1}\), making for simpler calculations. In fact, if you drop the \( \boldsymbol{R}^{-1} \) it is easier to see what is going on in the different components of the \( \boldsymbol{C} \) matrix. For example, print \( \boldsymbol{X}’ \boldsymbol{X} \) and you’ll get the sum of observations for the overall mean and for each of the levels of the fixed effect factors. Give it a try with the other submatrices too!

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

XpXnoR=t(X)%*%X

XpXnoR

# (Intercept) VMarvellous VVictory N0.2cwt N0.4cwt N0.6cwt

#(Intercept) 72 24 24 18 18 18

#VMarvellous 24 24 0 6 6 6

#VVictory 24 0 24 6 6 6

#N0.2cwt 18 6 6 18 0 0

#N0.4cwt 18 6 6 0 18 0

#N0.6cwt 18 6 6 0 0 18

#VMarvellous:N0.2cwt 6 6 0 6 0 0

#VVictory:N0.2cwt 6 0 6 6 0 0

#VMarvellous:N0.4cwt 6 6 0 0 6 0

#VVictory:N0.4cwt 6 0 6 0 6 0

#VMarvellous:N0.6cwt 6 6 0 0 0 6

#VVictory:N0.6cwt 6 0 6 0 0 6

# VMarvellous:N0.2cwt VVictory:N0.2cwt VMarvellous:N0.4cwt

#(Intercept) 6 6 6

#VMarvellous 6 0 6

#VVictory 0 6 0

#N0.2cwt 6 6 0

#N0.4cwt 0 0 6

#N0.6cwt 0 0 0

#VMarvellous:N0.2cwt 6 0 0

#VVictory:N0.2cwt 0 6 0

#VMarvellous:N0.4cwt 0 0 6

#VVictory:N0.4cwt 0 0 0

#VMarvellous:N0.6cwt 0 0 0

#VVictory:N0.6cwt 0 0 0

# VVictory:N0.4cwt VMarvellous:N0.6cwt VVictory:N0.6cwt

#(Intercept) 6 6 6

#VMarvellous 0 6 0

#VVictory 6 0 6

#N0.2cwt 0 0 0

#N0.4cwt 6 0 0

#N0.6cwt 0 6 6

#VMarvellous:N0.2cwt 0 0 0

#VVictory:N0.2cwt 0 0 0

#VMarvellous:N0.4cwt 0 0 0

#VVictory:N0.4cwt 6 0 0

#VMarvellous:N0.6cwt 0 6 0

#VVictory:N0.6cwt 0 0 6

I will leave it here and come back to this problem as soon as I can.

† Incidentally, a lot of the theoretical development was supported by Shayle Searle (a Kiwi statistician and Henderson’s colleague in Cornell University).

6 thoughts on “Split-plot 1: How does a linear mixed model look like?”

You can also find this dataset in my package:
require(“agridat”)
?yates.oats

I included the field coordinates and discovered that there was a strong gradient across the field, which makes the modeling process more interesting if you want to include a linear term to model the spatial trend. Some plots are included.

Here’s my understanding of how Maxwell & Delaney use the term “split plot design” when applied to between-subject and within-subject factors in psychological experiments. What corresponds to a “whole plot” is a subject (i.e., person) in an experiment. Each whole-plot person gets only one level of the “between-subject” factor A. But each person gets all levels of the “within-subject” factor B. The levels of the within-subject factor are administered in a random order through time, so those different positions in time are the “split plots” or “sub plots”.

If I understand the oats data correctly, in psychology terminology they are from a two-factor, completely within-subject design. For each whole plot (person), every combination of both factors was administered, albeit in different random arrangements, which would be like different random orders through time for people in the experiment. Thus, as I tried to indicate in my comment linked above, the oats data don’t have the same structure as the “split plot” example from Maxwell & Delaney.

Thanks for the comment. In the second part of this post I’ll, eventually, go for an MCMC analysis of oats and see where I end up. Nomenclature differences across disciplines are confusing (to say it politely), which combined with moving from REML to MCMC made the whole exercise puzzling. With some luck we’ll end up on the same page.