Below is a simplified version of my data. I want to plot the Means using vertical bars with ggplot() + geom_bar
. There are a few things I want to do.
I want to separate the data where I have the data grouped vertically (=side by side/beside each other/in columns) according to Vfront (all "front" data on left, all "back" data on right).
I also want to separate the data where I have the data grouped horizontally (on top of each other/in rows) according to Manner (all "Stop" on top row, all "Fric" on bottom row).
Additionally, I want to have the different MedDors grouped per Target (in the NA, cor, incor, X order).
Target Manner Vfront MedDor Mean
p Stop front NA 0.60
p Stop back NA 0.59
p Stop front cor 0.58
p Stop back cor 0.56
p Stop front incor 0.52
p Stop back incor 0.52
p Stop front X 0.24
p Stop back X 0.52
b Stop front NA 0.42
b Stop back NA 0.39
b Stop front cor 0.37
b Stop back cor 0.42
b Stop front incor 0.36
b Stop back incor 0.33
b Stop front X 0.14
b Stop back X 0.39
f Fric front NA 0.27
f Fric back NA 0.23
f Fric front cor 0.19
f Fric back cor 0.40
f Fric front incor 0.13
f Fric back incor 0.32
f Fric front X 0.08
f Fric back X 0.13
v Fric front NA 0.24
v Fric back NA 0.18
v Fric front cor 0.17
v Fric back cor 0.11
v Fric front incor 0.25
v Fric back incor 0.16
v Fric front X 0.09
v Fric back X 0.16
So in total I should get something similar to the grouped data that I have below:
Front Back
pNA pcor pincor cX bNA bcor bincor bX pNA pcor pincor cX bNA bcor bincor bX
p b p b
fNA fcor fincor fX vNA vcor vincor vX fNA fcor fincor fX vNA vcor vincor vX
f v f v
I can do some basic filtering of data, and factoring to get certain orders and I know facet_grid(~Vfront)
gives me different columns according to Vfront
values (based on my data) but the divisions I am asking about is beyond my current R abilities.
We can use ggh4x::facet_nested
for nested facets like you want. If you want a certain order of facets, you need to create factor
columns with levels
that you desire; however, NA
will always come last, so we need to convert NA
to "NA"
.
library(ggplot2)
library(ggh4x)
library(dplyr)
library(tidyr)
df1 %>%
mutate(MedDor_f = factor(replace_na(MedDor, "NA") ,
levels = c("NA", "cor", "incor", "X")),
Manner_f = factor(Manner, levels = c("Stop", "Fric")),
Vfront_f = factor(Vfront, levels = c("front", "back"))) %>%
ggplot(aes(x = Target, y = Mean)) +
geom_bar(stat = "identity") +
facet_nested(rows = vars(Manner_f), cols = vars(Vfront_f, MedDor_f))
If you want the x-axis to have a free scale (like what we get in facet_wrap
), you need to add scales = "free_x", independent = "x"
to the facet_nested
function.
I have also looked at your previous question, and implemented that solution here (not sure whether you want that or not, but it looks nice).
df1 %>%
mutate(MedDor_f = factor(replace_na(MedDor, "NA") ,
levels = c("NA", "cor", "incor", "X")),
Manner_f = factor(Manner, levels = c("Stop", "Fric")),
Vfront_f = factor(Vfront, levels = c("front", "back")),
Deviation = Mean - 0.5) %>%
ggplot(aes(x = Target, y = Deviation)) +
geom_col(aes(fill = Deviation > 0), position = position_dodge()) +
geom_hline(yintercept = 0, linetype = "dashed", color = "black") +
scale_fill_manual(values = c("TRUE" = "cadetblue3", "FALSE" = "coral3")) +
theme_classic() +
scale_y_continuous(limits = c(-0.5, 0.5),
breaks = seq(-0.5, 0.5, by = 0.1),
labels = function(x) sprintf("%.1f", x + 0.5)) +
theme(legend.position = "bottom",
axis.ticks.x = element_blank()) +
facet_nested(rows = vars(Manner_f), cols = vars(Vfront_f, MedDor_f),
scales = "free_x", independent = "x")
Created on 2024-02-06 with reprex v2.0.2
If you don't want to use ggh4x
, then you need to use grid
, gtable
, and/or patchwork
or other similar libraries, get your individual plots and arrange them in a grid. I personally would spend some more time on figuring out why ggh4x
is not working, maybe updating my R version, etc., before going down that route. Good luck!