title: Plotting Three Levels of Nested Data Using ggplot and R
body: <p>I recently ran a few 2x3 Mixed ANOVAs for a neuroscience project with age and valence as predictors of correlation values. These analyses were ran three times, once for each ROI, or brain region. I can create point line plots that visualize the data for each ROI pretty much without issue:</p>
  <pre><code>#Dataframe creation and data import
  df &lt;- data.frame(matrix(NA, nrow = 6, 
                          ncol = 1, 
                          dimnames = list(1:6, &quot;Age&quot;)))
  df$Age &lt;-c(rep(&quot;Child&quot;, 3), rep(&quot;Adult&quot;, 3))
  df$Valence &lt;- c(rep(c(&quot;Negative&quot;, &quot;Mixed&quot;, &quot;Positive&quot;),2))
  df$Cor &lt;- c(0.319, 0.303, 0.278, 0.200, 0.230, 0.216)
  df$ci &lt;- c(0.0648, 0.0548, 0.0557, 0.0631, 0.0542, 0.0649)
  
  #Plotting
  ggplot(df, aes(x = Age, y = Cor, group = Valence, color = Valence)) + 
    stat_summary(geom=&quot;pointrange&quot;, position=position_dodge(width = .2), fun.data = NULL) +
    stat_summary(geom=&quot;line&quot;, position=position_dodge(width = .2), fun.data = NULL) +
    geom_errorbar(aes(ymin = Cor - ci, ymax = Cor + ci), size= 0.3, width=0.2, position=position_dodge(width = .2)) +
    scale_fill_hue(name=&quot;Valence Type&quot;, breaks=c(&quot;Negative&quot;, &quot;Mixed&quot;, &quot;Positive&quot;), labels=c(&quot;Negative&quot;, &quot;Mixed&quot;, &quot;Positive&quot;)) +
    scale_x_discrete(name = &quot;Age Groups&quot;,  
                     labels = c(&quot;Child&quot;, &quot;Adult&quot;)) +
    scale_y_continuous(limits=c(0.10,0.40)) +
    ggtitle(&quot;Representational Similarity By Age and Valence&quot;) + 
    labs(y=&quot;Mean Correlation Value&quot;) + 
    theme_bw() +
    theme(title = element_text(face=&quot;bold&quot;, size=14)) +
    theme(axis.text.x = element_text(size=14, color = &quot;Black&quot;)) +
    theme(axis.text.y = element_text(size=14, color = &quot;Black&quot;))
  </code></pre>
  <p>However, what I'd love to do is consolidate the three separate plots into one so that the results of all three ROIs are represented in the same image; something like the image below, where the results of each ROI appear side by side of one another:
  <a href="https://i.stack.imgur.com/I6Odd.jpg" rel="nofollow noreferrer">MS Paint Rendering of my Scripting Inadequacies</a></p>
  <p>I've had no luck in finding a scripting solution to this problem, though. I thought maybe I could try nesting X axis values, since that's what I'm doing conceptually and that of course didn't work. I tried combining the ROI and Age factors, such that I then had &quot;Child, AMY&quot;, &quot;Adult, AMY&quot;, &quot;Child, NAcc&quot;, etc., but using a point line format, the lines extended across ROIs, which is not ideal. Point Line is my preference in visualization due to the research in biases present when reading bar plots, but if someone has a good solution to this using bar plots, I wouldn't fight it.</p>
  <p>I'm including a summary dataframe and my boilerplate ggplot script below. Any help, even if it's just telling me that what I'm trying to do is not possible, is greatly appreciated!</p>
  <pre><code>#Dataframe creation and data import
  df &lt;- data.frame(matrix(NA, nrow = 18, 
                              ncol = 1, 
                              dimnames = list(1:18, &quot;Age&quot;)))
  df$Age &lt;-c(rep(&quot;Child&quot;, 9), rep(&quot;Adult&quot;, 9))
  df$Valence &lt;- c(rep(c(rep(&quot;Negative&quot;,3), rep(&quot;Mixed&quot;,3), rep(&quot;Positive&quot;,3)),2))
  df$ROI &lt;- rep(c(&quot;AMY&quot;, &quot;NAcc&quot;, &quot;vmPFC&quot;), 6)
  df$Cor &lt;- c(0.229, 0.268, 0.319, 0.236, 0.260, 0.303, 0.213, 0.236, 0.278, 0.188, 0.205, 0.200, 0.221, 0.226, 0.230, 0.208, 0.210, 0.216)
  df$ci &lt;- c(0.0474, 0.0675, 0.0648, 0.0445, 0.0456, 0.0548, 0.0531, 0.0518, 0.0557, 0.0485, 0.0727, 0.0631, 0.0336, 0.0541, 0.0542, 0.0430, 0.0604, 0.0649)
  
  #Plotting
  ggplot(df, aes(x = Age, y = Cor, group = Valence, color = Valence)) + 
    stat_summary(geom=&quot;pointrange&quot;, position=position_dodge(width = .2), fun.data = NULL) +
    stat_summary(geom=&quot;line&quot;, position=position_dodge(width = .2), fun.data = NULL) +
    geom_errorbar(aes(ymin = Cor - ci, ymax = Cor + ci), size= 0.3, width=0.2, position=position_dodge(width = .2)) +
    scale_fill_hue(name=&quot;Valence Type&quot;, breaks=c(&quot;Negative&quot;, &quot;Mixed&quot;, &quot;Positive&quot;), labels=c(&quot;Negative&quot;, &quot;Mixed&quot;, &quot;Positive&quot;)) +
    scale_x_discrete(name = &quot;Age Groups&quot;,  
                     labels = c(&quot;Child&quot;, &quot;Adult&quot;)) +
    scale_y_continuous(limits=c(0.10,0.40)) +
    ggtitle(&quot;Representational Similarity By Age and Valence&quot;) + 
    labs(y=&quot;Mean Correlation Value&quot;) + 
    theme_bw() +
    theme(title = element_text(face=&quot;bold&quot;, size=14)) +
    theme(axis.text.x = element_text(size=14, color = &quot;Black&quot;)) +
    theme(axis.text.y = element_text(size=14, color = &quot;Black&quot;))
  </code></pre>