afex_plot {afex}  R Documentation 
mway Plot with Error Bars and Raw Data
Description
Plots results from factorial experiments. Estimated marginal means and error bars are plotted in the foreground, raw data is plotted in the background. Error bars can be based on different standard errors (e.g., modelbased, withinsubjects, betweensubjects). Functions described here return a ggplot2 plot object, thus allowing further customization of the plot.
afex_plot
is the user friendly function that does data preparation
and plotting. It also allows to only return the prepared data (return
= "data"
).
interaction_plot
does the plotting when a trace
factor is
present. oneway_plot
does the plotting when a trace
factor is
absent.
Usage
afex_plot(object, ...)
## S3 method for class 'afex_aov'
afex_plot(
object,
x,
trace,
panel,
mapping,
error = "model",
error_ci = TRUE,
error_level = 0.95,
error_arg = list(width = 0),
data_plot = TRUE,
data_geom,
data_alpha = 0.5,
data_color = "darkgrey",
data_arg = list(),
point_arg = list(),
line_arg = list(),
emmeans_arg = list(),
dodge = 0.5,
return = "plot",
factor_levels = list(),
legend_title,
...
)
## S3 method for class 'mixed'
afex_plot(
object,
x,
trace,
panel,
mapping,
id,
error = "model",
error_ci = TRUE,
error_level = 0.95,
error_arg = list(width = 0),
data_plot = TRUE,
data_geom,
data_alpha = 0.5,
data_color = "darkgrey",
data_arg = list(),
point_arg = list(),
line_arg = list(),
emmeans_arg = list(),
dodge = 0.5,
return = "plot",
factor_levels = list(),
legend_title,
...
)
## S3 method for class 'merMod'
afex_plot(
object,
x,
trace,
panel,
mapping,
id,
error = "model",
error_ci = TRUE,
error_level = 0.95,
error_arg = list(width = 0),
data_plot = TRUE,
data_geom,
data_alpha = 0.5,
data_color = "darkgrey",
data_arg = list(),
point_arg = list(),
line_arg = list(),
emmeans_arg = list(),
dodge = 0.5,
return = "plot",
factor_levels = list(),
legend_title,
...
)
## Default S3 method:
afex_plot(
object,
x,
trace,
panel,
mapping,
id,
dv,
data,
within_vars,
between_vars,
error = "model",
error_ci = TRUE,
error_level = 0.95,
error_arg = list(width = 0),
data_plot = TRUE,
data_geom,
data_alpha = 0.5,
data_color = "darkgrey",
data_arg = list(),
point_arg = list(),
line_arg = list(),
emmeans_arg = list(),
dodge = 0.5,
return = "plot",
factor_levels = list(),
legend_title,
...
)
interaction_plot(
means,
data,
mapping = c("shape", "lineytpe"),
error_plot = TRUE,
error_arg = list(width = 0),
data_plot = TRUE,
data_geom = ggplot2::geom_point,
data_alpha = 0.5,
data_color = "darkgrey",
data_arg = list(),
point_arg = list(),
line_arg = list(),
dodge = 0.5,
legend_title,
col_x = "x",
col_y = "y",
col_trace = "trace",
col_panel = "panel",
col_lower = "lower",
col_upper = "upper"
)
oneway_plot(
means,
data,
mapping = "",
error_plot = TRUE,
error_arg = list(width = 0),
data_plot = TRUE,
data_geom = ggbeeswarm::geom_beeswarm,
data_alpha = 0.5,
data_color = "darkgrey",
data_arg = list(),
point_arg = list(),
legend_title,
col_x = "x",
col_y = "y",
col_panel = "panel",
col_lower = "lower",
col_upper = "upper"
)
Arguments
object 

... 
currently ignored. 
x 
A 
trace 
An optional 
panel 
An optional 
mapping 
A 
error 
A scalar 
error_ci 
Logical. Should error bars plot confidence intervals
(= 
error_level 
Numeric value between 0 and 1 determing the width of the confidence interval. Default is .95 corresponding to a 95% confidence interval. 
error_arg 
A 
data_plot 

data_geom 
Geom 
data_alpha 
numeric 
data_color 
color that should be used for the data in the background.
Default is 
data_arg 
A 
point_arg , line_arg 
A 
emmeans_arg 
A 
dodge 
Numerical amount of dodging of factorlevels on xaxis. Default
is 
return 
A scalar 
factor_levels 
A 
legend_title 
A scalar 
id 
An optional 
dv 
An optional scalar 
data 
For the 
within_vars , between_vars 
For the 
means 

error_plot 

col_y , col_x , col_trace , col_panel 
A scalar 
col_lower , col_upper 
A scalar 
Details
afex_plot
obtains the estimated marginal means via
emmeans
and aggregates the raw data to the same
level. It then calculates the desired confidence interval or standard error
(see below) and passes the prepared data to one of the two plotting
functions: interaction_plot
when trace
is specified and
oneway_plot
otherwise.
Error Bars
Error bars provide a grahical representation of the
variability of the estimated means and should be routinely added to results
figures. However, there exist several possibilities which particular
measure of variability to use. Because of this, any figure depicting error
bars should be accompanied by a note detailing which measure the error bars
shows. The present functions allow plotting of different types of
confidence intervals (if error_ci = TRUE
, the default) or standard
errors (if error_ci = FALSE
).
A further complication is that readers routinely misinterpret confidence intervals. The most common error is to assume that nonoverlapping error bars indicate a significant difference (e.g., Belia et al., 2005). This is often too strong an assumption. (see e.g., Cumming & Finch, 2005; Knol et al., 2011; Schenker & Gentleman, 2005). For example, in a fully betweensubjects design in which the error bars depict 95% confidence intervals and groups are of approximately equal size and have equal variance, even error bars that overlap by as much as 50% still correspond to p < .05. Error bars that are just touching roughly correspond to p = .01.
In the case of designs involving repeatedmeasures factors the usual confidence intervals or standard errors (i.e., modelbased confidence intervals or intervals based on the standard error of the mean) cannot be used to gauge significant differences as this requires knowledge about the correlation between measures. One popular alternative in the psychological literature are intervals based on withinsubjects standard errors/confidence intervals (e.g., Cousineau & O'Brien, 2014). These attempt to control for the correlation across individuals and thereby allow judging differences between repeatedmeasures condition. As a downside, when using withinsubjects intervals no comparisons across betweensubjects conditions or with respect to a fixedvalue are possible anymore.
In the case of a mixeddesign, no single type of error bar is possible that
allows comparison across all conditions. Likewise, for mixed models
involving multiple crossed random effects, no single set of error
bars (or even data aggregation) adequately represent the true varibility in
the data and adequately allows for "inference by eye". Therefore, special
care is necessary in such cases. One possiblity is to avoid error bars
altogether and plot only the raw data in the background (with error =
"none"
). The raw data in the background still provides a visual impression
of the variability in the data and the precision of the mean estimate, but
does not as easily suggest an incorrect inferences. Another possibility is
to use the modelbased standard error and note in the figure caption that
it does not permit comparisons across repeatedmeasures factors.
The following "rules of eye" (Cumming and Finch, 2005) hold, when permitted by design (i.e., withinsubjects bars for withinsubjects comparisons; other variants for betweensubjects comparisons), and groups are approximately equal in size and variance. Note that for more complex designs ususally analyzed with mixed models, such as designs involving complicated dependencies across data points, these rules of thumbs may be highly misleading.

p < .05 when the overlap of the 95% confidence intervals (CIs) is no more than about half the average margin of error, that is, when proportion overlap is about .50 or less.

p < .01 when the two CIs do not overlap, that is, when proportion overlap is about 0 or there is a positive gap.

p < .05 when the gap between standard error (SE) bars is at least about the size of the average SE, that is, when the proportion gap is about 1 or greater.

p < .01 when the proportion gap between SE bars is about 2 or more.
Implemented Standard Errors
The following lists the
implemented approaches to calculate confidence intervals (CIs) and standard
errors (SEs). CIs are based on the SEs using the tdistribution with
degrees of freedom based on the cell or group size. For ANOVA models,
afex_plot
attempts to warn in case the chosen approach is misleading
given the design (e.g., modelbased error bars for purely
withinsubjects plots). For mixed
models, no such warnings are
produced, but users should be aware that all options beside "model"
are not actually appropriate and have only heuristic value. But then again,
"model"
based error bars do not permit comparisons for factors
varying within one of the randomeffects grouping factors (i.e., factors
for which randomslopes should be estimated).
"model"
Uses modelbased CIs and SEs. For ANOVAs, the variant based on the
lm
ormlm
model (i.e.,emmeans_arg = list(model = "multivariate")
) seems generally preferrable."mean"
Calculates the standard error of the mean for each cell ignoring any repeatedmeasures factors.
"within"
or"CMO"
Calculates withinsubjects SEs using the CosineauMoreyO'Brien (Cousineau & O'Brien, 2014) method. This method is based on a double normalization of the data. SEs and CIs are then calculated independently for each cell (i.e., if the desired output contains betweensubjects factors, SEs are calculated for each cell including the betweensubjects factors).
"between"
First aggregates the data per participant and then calculates the SEs for each betweensubjects condition. Results in one SE and tquantile for all conditions in purely withinsubjects designs.
"none"
orNULL
Suppresses calculation of SEs and plots no error bars.
For mixed
models, the withinsubjects/repeatedmeasures factors are
relative to the chosen id
effects grouping factor. They are
automatically detected based on the randomslopes of the randomeffects
grouping factor in id
. All other factors are treated as
independentsamples or betweensubjects factors.
Value
Returns a ggplot2 plot (i.e., object of class c("gg",
"ggplot")
) unless return = "data"
.
Note
Only the DV/response variable can be called y
, but no
factor/variable used for plotting.
References
Belia, S., Fidler, F., Williams, J., & Cumming, G. (2005). Researchers Misunderstand Confidence Intervals and Standard Error Bars. Psychological Methods, 10(4), 389396. https://doi.org/10.1037/1082989X.10.4.389
Cousineau, D., & O'Brien, F. (2014). Error bars in withinsubject designs: a comment on Baguley (2012). Behavior Research Methods, 46(4), 11491151. https://doi.org/10.3758/s134280130441z
Cumming, G., & Finch, S. (2005). Inference by Eye: Confidence Intervals and How to Read Pictures of Data. American Psychologist, 60(2), 170180. https://doi.org/10.1037/0003066X.60.2.170
Knol, M. J., Pestman, W. R., & Grobbee, D. E. (2011). The (mis)use of overlap of confidence intervals to assess effect modification. European Journal of Epidemiology, 26(4), 253254. https://doi.org/10.1007/s1065401195638
Schenker, N., & Gentleman, J. F. (2001). On Judging the Significance of Differences by Examining the Overlap Between Confidence Intervals. The American Statistician, 55(3), 182186. https://doi.org/10.1198/000313001317097960
Examples
# note: use library("ggplot") to avoid "ggplot2::" in the following
##################################################################
## 2factor WithinSubject Design ##
##################################################################
data(md_12.1)
aw < aov_ez("id", "rt", md_12.1, within = c("angle", "noise"))
##
## Basic Interaction Plots 
##
## all examples require emmeans and ggplot2:
if (requireNamespace("emmeans") && requireNamespace("ggplot2")) {
afex_plot(aw, x = "angle", trace = "noise")
# or: afex_plot(aw, x = ~angle, trace = ~noise)
afex_plot(aw, x = "noise", trace = "angle")
### For withinsubject designs, using withinsubject CIs is better:
afex_plot(aw, x = "angle", trace = "noise", error = "within")
(p1 < afex_plot(aw, x = "noise", trace = "angle", error = "within"))
## use different themes for nicer graphs:
p1 + ggplot2::theme_bw()
}
## Not run:
p1 + ggplot2::theme_light()
p1 + ggplot2::theme_minimal()
p1 + jtools::theme_apa()
p1 + ggpubr::theme_pubr()
### set theme globally for R session:
ggplot2::theme_set(ggplot2::theme_bw())
### There are several ways to deal with overlapping points in the background besides alpha
# Using the default data geom and ggplot2::position_jitterdodge
afex_plot(aw, x = "noise", trace = "angle", error = "within", dodge = 0.3,
data_arg = list(
position =
ggplot2::position_jitterdodge(
jitter.width = 0,
jitter.height = 5,
dodge.width = 0.3 ## needs to be same as dodge
)))
# Overlapping points are shown as larger points using geom_count
afex_plot(aw, x = "noise", trace = "angle", error = "within", dodge = 0.5,
data_geom = ggplot2::geom_count)
# Using ggbeeswarm::geom_quasirandom (overlapping points shown in violin shape)
afex_plot(aw, x = "noise", trace = "angle", error = "within", dodge = 0.5,
data_geom = ggbeeswarm::geom_quasirandom,
data_arg = list(
dodge.width = 0.5, ## needs to be same as dodge
cex = 0.8,
width = 0.05 ## small value ensure data points match means
))
# Using ggbeeswarm::geom_beeswarm (overlapping points are adjacent on yaxis)
afex_plot(aw, x = "noise", trace = "angle", error = "within", dodge = 0.5,
data_geom = ggbeeswarm::geom_beeswarm,
data_arg = list(
dodge.width = 0.5, ## needs to be same as dodge
cex = 0.8))
# Do not display points, but use a violinplot: ggplot2::geom_violin
afex_plot(aw, x = "noise", trace = "angle", error = "within",
data_geom = ggplot2::geom_violin,
data_arg = list(width = 0.5))
# violinplots with color: ggplot2::geom_violin
afex_plot(aw, x = "noise", trace = "angle", error = "within",
mapping = c("linetype", "shape", "fill"),
data_geom = ggplot2::geom_violin,
data_arg = list(width = 0.5))
# do not display points, but use a boxplot: ggplot2::geom_boxplot
afex_plot(aw, x = "noise", trace = "angle", error = "within",
data_geom = ggplot2::geom_boxplot,
data_arg = list(width = 0.3))
# combine points with boxplot: ggpol::geom_boxjitter
afex_plot(aw, x = "noise", trace = "angle", error = "within",
data_geom = ggpol::geom_boxjitter,
data_arg = list(width = 0.3))
## hides error bars!
# nicer variant of ggpol::geom_boxjitter
afex_plot(aw, x = "noise", trace = "angle", error = "within",
mapping = c("shape", "fill"),
data_geom = ggpol::geom_boxjitter,
data_arg = list(
width = 0.3,
jitter.params = list(width = 0, height = 10),
outlier.intersect = TRUE),
point_arg = list(size = 2.5),
error_arg = list(linewidth = 1.5, width = 0))
# nicer variant of ggpol::geom_boxjitter without lines
afex_plot(aw, x = "noise", trace = "angle", error = "within", dodge = 0.7,
mapping = c("shape", "fill"),
data_geom = ggpol::geom_boxjitter,
data_arg = list(
width = 0.5,
jitter.params = list(width = 0, height = 10),
outlier.intersect = TRUE),
point_arg = list(size = 2.5),
line_arg = list(linetype = 0),
error_arg = list(linewidth = 1.5, width = 0))
### we can also use multiple geoms for the background by passing a list of geoms
afex_plot(aw, x = "noise", trace = "angle", error = "within",
data_geom = list(
ggplot2::geom_violin,
ggplot2::geom_point
))
## with separate extra arguments:
afex_plot(aw, x = "noise", trace = "angle", error = "within",
dodge = 0.5,
data_geom = list(
ggplot2::geom_violin,
ggplot2::geom_point
),
data_arg = list(
list(width = 0.4),
list(position =
ggplot2::position_jitterdodge(
jitter.width = 0,
jitter.height = 5,
dodge.width = 0.5 ## needs to be same as dodge
)))
)
## End(Not run)
##
## OneWay Plots 
##
## Not run:
afex_plot(aw, x = "angle", error = "within") ## default
## with color we need larger points
afex_plot(aw, x = "angle", mapping = "color", error = "within",
point_arg = list(size = 2.5),
error_arg = list(linewidth = 1.5, width = 0.05))
afex_plot(aw, x = "angle", error = "within", data_geom = ggpol::geom_boxjitter)
## nicer
afex_plot(aw, x = "angle", error = "within", data_geom = ggpol::geom_boxjitter,
mapping = "fill", data_alpha = 0.7,
data_arg = list(
width = 0.6,
jitter.params = list(width = 0.07, height = 10),
outlier.intersect = TRUE
),
point_arg = list(size = 2.5),
error_arg = list(linewidth = 1.5, width = 0.05))
## we can use multiple geoms with separate argument lists:
afex_plot(aw, x = "angle", error = "within",
data_geom =
list(ggplot2::geom_violin, ggplot2::geom_boxplot),
data_arg =
list(list(width = 0.7), list(width = 0.1)))
## we can add a line connecting the means using geom_point(aes(group = 1)):
afex_plot(aw, x = "angle", error = "within") +
ggplot2::geom_line(ggplot2::aes(group = 1))
## we can also add lines connecting the individual datapoint in the bg.
# to deal with overlapping points, we use geom_count and make means larger
afex_plot(aw, x = "angle", error = "within",
data_geom = list(ggplot2::geom_count, ggplot2::geom_line),
data_arg = list(list(), list(mapping = ggplot2::aes(group = id))),
point_arg = list(size = 2.5),
error_arg = list(width = 0, linewidth = 1.5)) +
ggplot2::geom_line(ggplot2::aes(group = 1), linewidth = 1.5)
## Oneway plots also supports panels:
afex_plot(aw, x = "angle", panel = "noise", error = "within")
## And panels with lines:
afex_plot(aw, x = "angle", panel = "noise", error = "within") +
ggplot2::geom_line(ggplot2::aes(group = 1))
## For more complicated plots it is easier to attach ggplot2:
library("ggplot2")
## We can hide geoms by plotting them in transparent colour and add them
## afterward to use a mapping not directly supported.
## For example, the next plot adds a line to a oneway plot with panels, but
## with all geoms in the foreground having a colour conditional on the panel.
afex_plot(aw, x = "angle", panel = "noise", error = "within",
point_arg = list(color = "transparent"),
error_arg = list(color = "transparent")) +
geom_point(aes(color = panel)) +
geom_linerange(aes(color = panel, ymin = lower, ymax = upper)) +
geom_line(aes(group = 1, color = panel)) +
guides(color = guide_legend(title = "NOISE"))
## Note that we need to use guides explicitly, otherwise the legend title would
## be "panel". legend_title does not work in this case.
##
## Other Basic Options 
##
## relabel factor levels via factor_levels (with message)
afex_plot(aw, x = "noise", trace = "angle",
factor_levels = list(angle = c("0°", "4°", "8°"),
noise = c("Absent", "Present")))
## factor_levels allows named vectors which enable reordering the factor levels
### and renaming subsets of levels:
afex_plot(aw, x = "noise", trace = "angle",
factor_levels = list(
angle = c(X8 = "8°", X4 = "4°", X0 = "0°"),
noise = c(present = "Present")
)
)
## Change title of legend
afex_plot(aw, x = "noise", trace = "angle",
legend_title = "Noise Condition")
## for plots with few factor levels, smaller dodge might be better:
afex_plot(aw, x = "angle", trace = "noise", dodge = 0.25)
#################################################################
## 4factor Mixed Design ##
#################################################################
data(obk.long, package = "afex")
a1 < aov_car(value ~ treatment * gender + Error(id/(phase*hour)),
data = obk.long, observed = "gender")
## too difficult to see anything
afex_plot(a1, ~phase*hour, ~treatment) +
ggplot2::theme_light()
## better
afex_plot(a1, ~hour, ~treatment, ~phase) +
ggplot2::theme_light()
## even better
afex_plot(a1, ~hour, ~treatment, ~phase,
dodge = 0.65,
data_arg = list(
position =
ggplot2::position_jitterdodge(
jitter.width = 0,
jitter.height = 0.2,
dodge.width = 0.65 ## needs to be same as dodge
),
color = "darkgrey")) +
ggplot2::theme_classic()
# with color instead of linetype to separate trace factor
afex_plot(a1, ~hour, ~treatment, ~phase,
mapping = c("shape", "color"),
dodge = 0.65,
data_arg = list(
position =
ggplot2::position_jitterdodge(
jitter.width = 0,
jitter.height = 0.2,
dodge.width = 0.65 ## needs to be same as dodge
))) +
ggplot2::theme_light()
# only color to separate trace factor
afex_plot(a1, ~hour, ~treatment, ~phase,
mapping = c("color"),
dodge = 0.65,
data_color = NULL, ## needs to be set to NULL to avoid error
data_arg = list(
position =
ggplot2::position_jitterdodge(
jitter.width = 0,
jitter.height = 0.2,
dodge.width = 0.65 ## needs to be same as dodge
))) +
ggplot2::theme_classic()
## plot involving all 4 factors:
afex_plot(a1, ~hour, ~treatment, ~gender+phase,
dodge = 0.65,
data_arg = list(
position =
ggplot2::position_jitterdodge(
jitter.width = 0,
jitter.height = 0.2,
dodge.width = 0.65 ## needs to be same as dodge
),
color = "darkgrey")) +
ggplot2::theme_bw()
##
## Different Standard Errors Available 
##
## purely withindesign
cbind(
afex_plot(a1, ~phase, ~hour,
error = "model", return = "data")$means[,c("phase", "hour", "y", "SE")],
multivariate = afex_plot(a1, ~phase, ~hour,
error = "model", return = "data")$means$error,
mean = afex_plot(a1, ~phase, ~hour,
error = "mean", return = "data")$means$error,
within = afex_plot(a1, ~phase, ~hour,
error = "within", return = "data")$means$error,
between = afex_plot(a1, ~phase, ~hour,
error = "between", return = "data")$means$error)
## mixed design
cbind(
afex_plot(a1, ~phase, ~treatment,
error = "model", return = "data")$means[,c("phase", "treatment", "y", "SE")],
multivariate = afex_plot(a1, ~phase, ~treatment,
error = "model", return = "data")$means$error,
mean = afex_plot(a1, ~phase, ~treatment,
error = "mean", return = "data")$means$error,
within = afex_plot(a1, ~phase, ~treatment,
error = "within", return = "data")$means$error,
between = afex_plot(a1, ~phase, ~treatment,
error = "between", return = "data")$means$error)
## End(Not run)
##################################################################
## Mixed Models ##
##################################################################
if (requireNamespace("MEMSS") &&
requireNamespace("emmeans") &&
requireNamespace("ggplot2")) {
data("Machines", package = "MEMSS")
m1 < mixed(score ~ Machine + (MachineWorker), data=Machines)
pairs(emmeans::emmeans(m1, "Machine"))
# contrast estimate SE df t.ratio p.value
# A  B 7.966667 2.420850 5 3.291 0.0481
# A  C 13.916667 1.540100 5 9.036 0.0007
# B  C 5.950000 2.446475 5 2.432 0.1253
## Default (i.e., modelbased) error bars suggest no difference between Machines.
## This contrasts with pairwise comparisons above.
afex_plot(m1, "Machine")
## Impression from withinsubject error bars is more in line with pattern of differences.
afex_plot(m1, "Machine", error = "within")
}
## Not run:
data("fhch2010") # load
fhch < droplevels(fhch2010[ fhch2010$correct,]) # remove errors
### following model should take less than a minute to fit:
mrt < mixed(log_rt ~ task*stimulus*frequency + (stimulus*frequencyid)+
(taskitem), fhch, method = "S", expand_re = TRUE)
## way too many points in background:
afex_plot(mrt, "stimulus", "frequency", "task")
## better to restrict plot of data to one randomeffects grouping variable
afex_plot(mrt, "stimulus", "frequency", "task", id = "id")
## when plotting data from a single random effect, different error bars are possible:
afex_plot(mrt, "stimulus", "frequency", "task", id = "id", error = "within")
afex_plot(mrt, "stimulus", "frequency", "task", id = "id", error = "mean")
## compare visual impression with:
pairs(emmeans::emmeans(mrt, c("stimulus", "frequency"), by = "task"))
## same logic also possible for other randomeffects grouping factor
afex_plot(mrt, "stimulus", "frequency", "task", id = "item")
## withinitem error bars are misleading here. task is sole withinitems factor.
afex_plot(mrt, "stimulus", "frequency", "task", id = "item", error = "within")
## CIs based on standard error of mean look small, but not unreasonable given results.
afex_plot(mrt, "stimulus", "frequency", "task", id = "item", error = "mean")
### compare distribution of individual data for different random effects:
## requires package cowplot
p_id < afex_plot(mrt, "stimulus", "frequency", "task", id = "id",
error = "within", dodge = 0.7,
data_geom = ggplot2::geom_violin,
mapping = c("shape", "fill"),
data_arg = list(width = 0.7)) +
ggplot2::scale_shape_manual(values = c(4, 17)) +
ggplot2::labs(title = "ID")
p_item < afex_plot(mrt, "stimulus", "frequency", "task", id = "item",
error = "within", dodge = 0.7,
data_geom = ggplot2::geom_violin,
mapping = c("shape", "fill"),
data_arg = list(width = 0.7)) +
ggplot2::scale_shape_manual(values = c(4, 17)) +
ggplot2::labs(title = "Item")
### see: https://cran.rproject.org/package=cowplot/vignettes/shared_legends.html
p_comb < cowplot::plot_grid(
p_id + ggplot2::theme_light() + ggplot2::theme(legend.position="none"),
p_item + ggplot2::theme_light() + ggplot2::theme(legend.position="none")
)
legend < cowplot::get_legend(p_id + ggplot2::theme(legend.position="bottom"))
cowplot::plot_grid(p_comb, legend,
ncol = 1,
rel_heights = c(1, 0.1))
##
## Support for lme4::lmer 
##
Oats < nlme::Oats
## afex_plot does currently not support implicit nesting: (1Block/Variety)
## Instead, we need to create the factor explicitly
Oats$VarBlock < Oats$Variety:Oats$Block
Oats.lmer < lmer(yield ~ Variety * factor(nitro) + (1VarBlock) + (1Block),
data = Oats)
afex_plot(Oats.lmer, "nitro", "Variety")
afex_plot(Oats.lmer, "nitro", panel = "Variety")
##################################################################
## Default Method works for Models Supported by emmeans ##
##################################################################
## lm
warp.lm < lm(breaks ~ wool * tension, data = warpbreaks)
afex_plot(warp.lm, "tension")
afex_plot(warp.lm, "tension", "wool")
## poisson glm
ins < data.frame(
n = c(500, 1200, 100, 400, 500, 300),
size = factor(rep(1:3,2), labels = c("S","M","L")),
age = factor(rep(1:2, each = 3)),
claims = c(42, 37, 1, 101, 73, 14))
ins.glm < glm(claims ~ size + age + offset(log(n)),
data = ins, family = "poisson")
afex_plot(ins.glm, "size", "age")
## binomial glm adapted from ?predict.glm
ldose < factor(rep(0:5, 2))
numdead < c(1, 4, 9, 13, 18, 20, 0, 2, 6, 10, 12, 16)
sex < factor(rep(c("M", "F"), c(6, 6)))
SF < numdead/20 ## dv should be a vector, no matrix
budworm.lg < glm(SF ~ sex*ldose, family = binomial,
weights = rep(20, length(numdead)))
afex_plot(budworm.lg, "ldose")
afex_plot(budworm.lg, "ldose", "sex") ## data point is hidden behind mean!
afex_plot(budworm.lg, "ldose", "sex",
data_arg = list(size = 4, color = "red"))
## nlme mixed model
data(Oats, package = "nlme")
Oats$nitro < factor(Oats$nitro)
oats.1 < nlme::lme(yield ~ nitro * Variety,
random = ~ 1  Block / Variety,
data = Oats)
afex_plot(oats.1, "nitro", "Variety", data = Oats)
afex_plot(oats.1, "nitro", "Variety", data = Oats, id = "Block")
afex_plot(oats.1, "nitro", data = Oats)
afex_plot(oats.1, "nitro", data = Oats, id = c("Block", "Variety"))
afex_plot(oats.1, "nitro", data = Oats, id = "Block")
## End(Not run)