Documentation for ggsced
Offsetting Phase Change Lines across Panels using ggsced
It is generally the case that most multiple-baseline designs will not require heavy customization of the cross-panel phase change lines. However, in some cases, it my be necessary to introduce small offsets to specific portions of each phase change line to make their representations clearer and more interpretable. To revisit this process once more, with a more complicated design (i.e., mix of reversal and multiple-baseline) and arrangement of data (i.e., two series being explored across conditions and participants), let’s begin with a base representation per ggplot.
The initial, base code is provided below:
ggplot(data, aes(x = Session,
y = Value,
shape = Response,
# Note: Partial out each chunk of connected data by response types and condition
group = interaction(Response, Condition))) +
geom_line() +
geom_point() +
facet_grid(rows = vars(Participant)) +
theme_classic() +
# Note: Trim out the default facet labels, and modify the text and legend formatting
theme(
text = element_text(family = "Times New Roman", size = 14),
strip.text = element_blank(),
legend.title = element_blank(),
legend.position = "inside",
legend.position.inside = c(1, 1),
legend.justification.inside = c(1, 1)
)
Application of Text and Phase Change Annotations
As is evident from the above code, the base plot is fairly simple, but it is also missing some key annotations that are necessary for interpretation. To add these annotations, we introduce the respective phase/panel labels as well as the appropriate phase change annotations. As indicated here, the phase change lines are staggered across panels, which is the expected form for multiple-baseline designs. The ggsced helper function assists with preparing these annotations; however, there is a conspicuous area of overlap that can occur when the phase change lines are staggered across panels. Although this is a bit trivial in terms of its effect on our interpretation of the data, it is aesthetically displeasing and inconsistent with single-case design conventions.
The code for the base plot with annotations is provided below, which will be modified in the next section to introduce offsets to the phase change lines.
update_geom_defaults("text", list(family = "Times New Roman"))
panel_labels = data.frame(
Participant = unique(data$Participant),
label = levels(data$Participant),
Value = c(0, 22.5, 22.5),
Session = 25,
Response = unique(data$Response)[1], # Irrelevant
Condition = unique(data$Condition)[1] # Irrelevant
)
phase_labels = data.frame(
Participant = rep(unique(data$Participant)[1], 6), # Pull first participant 4x
label = c("Baseline",
"FR-Lowest",
"Baseline",
"FR-Inelastic",
"FR-Elastic",
"FR-Inelastic"), # Phase labels
Value = rep(25, 6),
Session = c(2, 5, 8, 11, 14, 18),
Response = unique(data$Response)[1], # Irrelevant
Condition = rep(unique(data$Condition)[1], 6) # Irrelevant
)
p <- ggplot(data, aes(x = Session,
y = Value,
shape = Response,
fill = Response,
group = interaction(Response, Condition))) +
geom_line() +
geom_point(size = 3) +
scale_shape_manual(values = c("Reinforcers" = 21,
"Responding" = 22)) +
scale_fill_manual(values = c("Reinforcers" = "white",
"Responding" = "black")) +
scale_x_continuous(breaks = c(1, 5, 10, 15, 20, 25),
limits = c(1, 25),
guide = guide_axis(cap = "both"),
expand = expansion(mult = c(0.025, 0.025))) +
scale_y_continuous(name = "Frequency (Responses, Reinforcers Delivered)",
breaks = c(0, 5, 10, 15, 20, 25),
limits = c(0, 25),
guide = guide_axis(cap = "both")) +
geom_text(data = panel_labels,
mapping = aes(label = label),
hjust = 1,
vjust = 0) +
geom_text(data = phase_labels,
mapping = aes(label = label),
hjust = 0.5,
vjust = 0.25) +
facet_grid(rows = vars(Participant),
axes = "all",
axis.labels = "margins") +
theme_classic() +
theme(
text = element_text(family = "Times New Roman", size = 14),
strip.text = element_blank(),
legend.title = element_blank(),
legend.position = "inside",
legend.position.inside = c(1, 1),
legend.justification.inside = c(1, 1)
)
staggered_pls = list(
'1' = c(3.5, 3.5, 3.5),
'2' = c(6.5, 6.5, 8.5),
'3' = c(9.5, 9.5, 11.5),
'4' = c(12.5, 16.5, 16.5),
'5' = c(15.5, 22.5, 19.5)
)
final_plot <- ggsced(p, legs = staggered_pls, print = FALSE)
grid.draw(final_plot)
Incorporating Offsets to Phase Change Lines
The ggsced function includes an argument for introducing offsets to specific phase change lines across panels. This is done via the offs argument, which takes a list of vectors that correspond to the phase change lines specified in the legs argument. The vectors should be of the same length as the number of panels, and should contain logical values indicating whether to apply an offset to the corresponding phase change line in each panel. That is, a simple TRUE/FALSE indicating which of the horizontal segments should be adjusted slightly in terms of height (Note: a number value can be provided to for additional flexibility).
The source code and resulting figure illustrates how the final plot can be modified to include offsets to specific phase change lines across panels.
update_geom_defaults("text", list(family = "Times New Roman"))
panel_labels = data.frame(
Participant = unique(data$Participant),
label = levels(data$Participant),
Value = c(0, 22.5, 22.5),
Session = 25,
Response = unique(data$Response)[1], # Irrelevant
Condition = unique(data$Condition)[1] # Irrelevant
)
phase_labels = data.frame(
Participant = rep(unique(data$Participant)[1], 6), # Pull first participant 4x
label = c("Baseline",
"FR-Lowest",
"Baseline",
"FR-Inelastic",
"FR-Elastic",
"FR-Inelastic"), # Phase labels
Value = rep(25, 6),
Session = c(2, 5, 8, 11, 14, 18),
Response = unique(data$Response)[1], # Irrelevant
Condition = rep(unique(data$Condition)[1], 6) # Irrelevant
)
p <- ggplot(data, aes(x = Session,
y = Value,
shape = Response,
fill = Response,
group = interaction(Response, Condition))) +
geom_line() +
geom_point(size = 3) +
scale_shape_manual(values = c("Reinforcers" = 21,
"Responding" = 22)) +
scale_fill_manual(values = c("Reinforcers" = "white",
"Responding" = "black")) +
scale_x_continuous(breaks = c(1, 5, 10, 15, 20, 25),
limits = c(1, 25),
guide = guide_axis(cap = "both"),
expand = expansion(mult = c(0.025, 0.025))) +
scale_y_continuous(name = "Frequency (Responses, Reinforcers Delivered)",
breaks = c(0, 5, 10, 15, 20, 25),
limits = c(0, 25),
guide = guide_axis(cap = "both")) +
geom_text(data = panel_labels,
mapping = aes(label = label),
hjust = 1,
vjust = 0) +
geom_text(data = phase_labels,
mapping = aes(label = label),
hjust = 0.5,
vjust = 0.25) +
facet_grid(rows = vars(Participant),
axes = "all",
axis.labels = "margins") +
theme_classic() +
theme(
text = element_text(family = "Times New Roman", size = 14),
strip.text = element_blank(),
legend.title = element_blank(),
legend.position = "inside",
legend.position.inside = c(1, 1),
legend.justification.inside = c(1, 1)
)
staggered_pls = list(
'1' = c(3.5, 3.5, 3.5),
'2' = c(6.5, 6.5, 8.5),
'3' = c(9.5, 9.5, 11.5),
'4' = c(12.5, 16.5, 16.5),
'5' = c(15.5, 22.5, 19.5)
)
offsets_pls = list(
'1' = c(F, F, F),
'2' = c(F, F, F),
'3' = c(F, F, F),
'4' = c(F, F, F),
# Note: See the one 'T' here, which will offset the phase change line for the final panel
'5' = c(T, F, F)
)
# Note: see argument for offs
final_plot <- ggsced(p, legs = staggered_pls, offs = offsets_pls, print = FALSE)
grid.draw(final_plot)
Summary and Takeaway Points
This post highlights some of the final functionality related to the ggsced package and how the methods provided can be used to support single-case design figure construction as well as provide flexibility for more complex and ambitious designs. The specific example provided here illustrates how to introduce offsets to specific phase change lines across panels in a multiple-baseline design, which is likely going to be the most common scenarios for users.