<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/mixed-models-for-anova-designs-with-one-observation-per-unit-of-observation-and-cell-of-the-design/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://singmann.org/mixed-models-for-anova-designs-with-one-observation-per-unit-of-observation-and-cell-of-the-design/"> Computational Psychology - Henrik Singmann</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Together with <a rel="nofollow" href="http://davidkellen.org/" target="_blank">David Kellen</a> I am currently working on an introductory chapter to mixed models for a book edited by Dan Spieler and Eric Schumacher (<a rel="nofollow" href="http://singmann.org/download/publications/singmann_kellen-introduction-mixed-models.pdf" target="_blank">the current version can be found here</a>). The goal is to provide a theoretical and practical introduction that is targeted mainly at experimental psychologists, neuroscientists, and others working with experimental designs and human data. The practical part focuses obviously on <code>R</code>, specifically on <code>lme4</code> and <code>afex</code>.</p>
<p>One part of the chapter was supposed to deal with designs that cannot be estimated with the <em>maximal random effects structure justified by the design</em> <span rel="{ 'api_user_id': '881472', 'pages': '', 'items': '{STGUHGIT}', 'format': '(%a%, %d%, %p%)', 'brackets': '', 'etal': '', 'separator': '', 'and': '' }"></span> because there is only one observation per participant and cell of the design. Such designs are the classical repeated-measures ANOVA design as ANOVA cannot deal with replicates at the cell levels (i.e., those are usually aggregated to yield one observation per cell and unit of observation). Based on my <a rel="nofollow" href="https://stats.stackexchange.com/a/131011/442" target="_blank">previous thoughts that turned out to be wrong</a> we wrote the following:</p>
<blockquote><p>Random Effects Structures for Traditional ANOVA Designs</p>
<p>The estimation of the maximal model is not possible when there is only one observation per participant and cell of a repeated-measures design. These designs are typically analyzed using a repeated-measures ANOVA. Currently, there are no clear guidelines on how to proceed in such situations, but we will try to provide some advice. If there is only a single random effects grouping factor, for example participants, we feel that instead of a mixed model, it is appropriate to use a standard repeated-measures ANOVA that addresses sphericity violations via the Greenhouse-Geisser correction.</p>
<p>One alternative strategy that employs mixed models and that we \emph{do not recommend} consists of using the random-intercept only model or removing the random slopes for the highest within-subject interaction. The resulting model assumes invariance of the omitted random effects across participants. If this assumption is violated such a model produces results that cannot be trusted <span rel="{ 'api_user_id': '881472', 'pages': '', 'items': '{STGUHGIT},{M2F33N9W}', 'format': '(%a%, %d%, %p%)', 'brackets': '', 'etal': '', 'separator': '', 'and': '' }"></span> . […]</p>
</blockquote>
<p>Fortunately, we asked <a rel="nofollow" href="http://jakewestfall.org/" target="_blank">Jake Westfall</a> to take a look at the chapter and Jake responded:</p>
<blockquote><p>I don’t think I agree with this. In the situation you describe, where we have a single random factor in a balanced ANOVA-like design with 1 observation per unit per cell, personally I am a proponent of the omit-the-the-highest-level-random-interaction approach. In this kind of design, the random slopes for the highest-level interaction are perfectly confounded with the trial-level error term (in more technical language, the model is only identifiable up to the sum of these two variance components), which is what causes the identifiability problems when one tries to estimate the full maximal model there. (You know all of this of course.) So two equivalent ways to make the model identifiable are to (1) omit the error term, i.e., force the residual variance to be 0, or (2) omit the random slopes for the highest-level interaction. Both of these approaches should (AFAIK) result in a statistically equivalent model, but lme4 does not provide an easy way to do (1), so I generally recommend (2). The important point here is that the standard errors should still be correct in either case — because these two variance components are confounded, omitting e.g. the random interaction slopes simply causes that omitted variance component to be implicitly added to the residual variance, where it is still incorporated into the standard errors of the fixed effects in the appropriate way (because the standard error of the fixed interaction looks roughly like sqrt[(var_error + var_interaction)/n_subjects]). I think one could pretty easily put together a little simulation that would demonstrate this.</p>
</blockquote>
<p>Hmm, that sounds very reasonable, but can my intuition on the random effects structure and mixed models really be that wrong? To investigate this I followed Jake’s advise and coded a short simulation that tested this and as it turns out, Jake is right and I was wrong.</p>
<p>In the simulation we will simulate a simple one-factor repeated-measures design with one factor with three levels. Importantly, each unit of observation will only have one observation per factor level. We will then fit this simulated data with both repeated-measures ANOVA and random-intercept only mixed and compare their <em>p</em>-values. Note again that for such a design we cannot estimate random slopes for the condition effect.</p>
<p>First, we need a few packages and set some parameters for our simulation:</p>
<pre data-enlighter-language="null">require(afex)
set_sum_contrasts() # for orthogonal sum-to-zero contrasts
require(MASS) 

NSIM &lt;- 1e4  # number of simulated data sets
NPAR &lt;- 30  # number of participants per cell
NCELLS &lt;- 3  # number of cells (i.e., groups)</pre>
<p>Now we need to generate the data. For this I employed an approach that is clearly not the most parsimonious, but most clearly follows the formulation of a mixed model that has random variability in the condition effect and on top of this residual variance (i.e., the two confounded factors).</p>
<p>We first create a bare bone <code>data.frame</code> with participant <code>id</code> and <code>condition</code> column and a corresponding <code>model.matrix</code>. Then we create the three random parameters (i.e., intercept and the two parameters for the three conditions) using a zero-centered multivarite normal with specified variance-covariance matrix. We then loop over the participant and estimate the predictions deriving from the three random effects parameters. Only after this we add uncorrelated residual variance to the observations for each simulated data set.</p>
<pre data-enlighter-language="null">dat &lt;- expand.grid(condition = factor(letters[seq_len(NCELLS)]),
                   id = factor(seq_len(NPAR)))
head(dat)
#   condition id
# 1         a  1
# 2         b  1
# 3         c  1
# 4         a  2
# 5         b  2
# 6         c  2

mm &lt;- model.matrix(~condition, dat)
head(mm)
#   (Intercept) condition1 condition2
# 1           1          1          0
# 2           1          0          1
# 3           1         -1         -1
# 4           1          1          0
# 5           1          0          1
# 6           1         -1         -1

Sigma_c_1 &lt;- matrix(0.6, NCELLS,NCELLS)
diag(Sigma_c_1) &lt;- 1
d_c_1 &lt;- replicate(NSIM, mvrnorm(NPAR, rep(0, NCELLS), Sigma_c_1), simplify = FALSE)

gen_dat &lt;- vector(&quot;list&quot;, NSIM)
for(i in seq_len(NSIM)) {
  gen_dat[[i]] &lt;- dat
  gen_dat[[i]]$dv &lt;- NA_real_
  for (j in seq_len(NPAR)) {
    gen_dat[[i]][(j-1)*3+(1:3),&quot;dv&quot;] &lt;- mm[1:3,] %*% d_c_1[[i]][j,]
  }
  gen_dat[[i]]$dv &lt;- gen_dat[[i]]$dv+rnorm(nrow(mm), 0, 1)
}</pre>
<p>Now we only need a function that estimates the ANOVA and mixed model for each data set and returns the p-value and loop over it.</p>
<pre data-enlighter-language="null">## functions returning p-value for ANOVA and mixed model
within_anova &lt;- function(data) {
  suppressWarnings(suppressMessages(
  a &lt;- aov_ez(id = &quot;id&quot;, dv = &quot;dv&quot;, data, within = &quot;condition&quot;, return = &quot;univariate&quot;, anova_table = list(es = &quot;none&quot;))
  ))
  c(without = a[[&quot;univariate.tests&quot;]][2,6],
    gg = a[[&quot;pval.adjustments&quot;]][1,2],
    hf = a[[&quot;pval.adjustments&quot;]][1,4])
}

within_mixed &lt;- function(data) {
  suppressWarnings(
    m &lt;- mixed(dv~condition+(1|id),data, progress = FALSE)  
  )
  c(mixed=anova(m)$`Pr(>F)`)
}

p_c1_within &lt;- vapply(gen_dat, within_anova, rep(0.0, 3))
m_c1_within &lt;- vapply(gen_dat, within_mixed, 0.0)</pre>
<p>The following graph shows the results (GG is the results using the Greenhouse-Geisser adjustment for sphericity violations).</p>
<pre data-enlighter-language="null">ylim &lt;- c(0, 700)
par(mfrow = c(1,3))
hist(p_c1_within[1,], breaks = 20, main = &quot;ANOVA (default)&quot;, xlab = &quot;p-value&quot;, ylim=ylim)
hist(p_c1_within[2,], breaks = 20, main = &quot;ANOVA (GG)&quot;, xlab = &quot;p-value&quot;, ylim=ylim)
hist(m_c1_within, breaks = 20, main = &quot;Random-Intercept Model&quot;, xlab = &quot;p-value&quot;, ylim=ylim)</pre>
<p><img data-orig-file="https://i0.wp.com/singmann.org/wp-content/uploads/2017/05/mixed_mode_anova_simulation_results.png?fit=672%2C480" data-orig-size="672,480" data-medium-file="https://i0.wp.com/singmann.org/wp-content/uploads/2017/05/mixed_mode_anova_simulation_results.png?fit=300%2C214" data-attachment-id="501" data-image-meta="{" data-image-description="" src="https://i0.wp.com/singmann.org/wp-content/uploads/2017/05/mixed_mode_anova_simulation_results.png?resize=490%2C350" data-permalink="http://singmann.org/mixed-models-for-anova-designs-with-one-observation-per-unit-of-observation-and-cell-of-the-design/mixed_mode_anova_simulation_results/" data-large-file="https://i0.wp.com/singmann.org/wp-content/uploads/2017/05/mixed_mode_anova_simulation_results.png?fit=490%2C350" alt="" data-image-title="mixed_mode_anova_simulation_results" sizes="(max-width: 490px) 100vw, 490px" data-comments-opened="1" class="wp-image-501" data-recalc-dims="1"></p>
<p>What these graph clearly shows is that the p-value distribution for the standard repeated-measures ANOVA and the random-intercept mixed model is virtually identical. This clearly shows that my intuition was wrong and Jake was right.</p>
<p>We also see that for ANOVA and mixed model the rate of significant findings with <em>p</em> &lt; .05 is slightly above the nominal level. More specifically:</p>
<pre data-enlighter-language="null">mean(p_c1_within[1,] &lt; 0.05) # ANOVA default
# [1] 0.0684
mean(p_c1_within[2,] &lt; 0.05) # ANOVA GG
# [1] 0.0529
mean(p_c1_within[3,] &lt; 0.05) # ANOVA HF
# [1] 0.0549
mean(m_c1_within &lt; 0.05)     # random-intercept mixed model
# [1] 0.0701</pre>
<p>These additional results indicate that maybe one also needs to adjust the degrees of freedom for mixed models for violations of sphericity. But this is not the topic of today’s post.</p>
<p>To sum this up, this simulation shows that removing the highest-order random slope seems to be the right decision if one wants to use a mixed model for a design with one observation per cell of the design and participant, but wants to implement the ‘maximal random effects structure’.</p>
<p>One more thing to note. <a rel="nofollow" href="http://ms.mcmaster.ca/~bolker/" target="_blank">Ben Bolker</a> raised the same issue and pointed us to one of his <a rel="nofollow" href="https://github.com/bbolker/iiscvisit/blob/master/workshops/mixedlab.rmd" target="_blank">example analyses of the <code>starling</code> data that is relevant to the current question</a>. We are very grateful that Jake and Ben took the time to go through our chapter!</p>
<p>You can also <a rel="nofollow" href="http://singmann.org/download/teaching/r/mixed_model_ANOVA_simulation2b.Rmd" target="_blank">download the <code>RMarkdown</code> file</a> of the simulation.</p>
<h3>References</h3>
<div>
<span>881472</span><br>
<span>{STGUHGIT};{STGUHGIT},{M2F33N9W}</span><br>
<span>apa</span><br>
<span>default</span><br>
<span>ASC</span><br>
<span>no</span><br>
<span></span><br>
<span></span><br>
<span></span><br>
<span></span><br>
<span></span><br>
<span></span><br>
<span></span><br>
<span></span><br>
<span></span><br>
<span></span><br>
<span>499</span><br>
<span>http://singmann.org/wp-content/plugins/zotpress/</span>
<div></div>
<p></div>
<p></p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://singmann.org/mixed-models-for-anova-designs-with-one-observation-per-unit-of-observation-and-cell-of-the-design/"> Computational Psychology - Henrik Singmann</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/5JuEEgO7fJ8" height="1"></a></div>