API Reference
Index
AnovaFun.AnovaResultAnovaFun.AxisKwargsAnovaFun.BarKwargsAnovaFun.BoxplotKwargsAnovaFun.DesignInfoAnovaFun.EmmeansResultAnovaFun.ErrorbarKwargsAnovaFun.FacetContextAnovaFun.FacetGridAnovaFun.FacetSpecAnovaFun.FigureKwargsAnovaFun.IndividualDataKwargsAnovaFun.JitterKwargsAnovaFun.LayoutKwargsAnovaFun.LegendKwargsAnovaFun.PairwiseResultAnovaFun.PlotConfigAnovaFun.PlotConfigAnovaFun.PlotPanelSpecAnovaFun.PowerResultAnovaFun.RaincloudComponentSpecAnovaFun.RaincloudKwargsAnovaFun.SampleSizeResultAnovaFun.ViolinKwargsAnovaFun.YLimKwargsAnovaFun.aggregateAnovaFun.all_factorsAnovaFun.anovaAnovaFun.anova_tableAnovaFun.between_factorsAnovaFun.check_homogeneityAnovaFun.ciAnovaFun.design_typeAnovaFun.emmeansAnovaFun.emmeans_tableAnovaFun.errorbar_limits!AnovaFun.fAnovaFun.factorsAnovaFun.fstatAnovaFun.independent_ttestAnovaFun.independent_ttestAnovaFun.mAnovaFun.m_ciAnovaFun.modelAnovaFun.n_effectsAnovaFun.n_idAnovaFun.pAnovaFun.paired_ttestAnovaFun.paired_ttestAnovaFun.pairwiseAnovaFun.pairwise_tableAnovaFun.plot_anova!AnovaFun.plot_sample_sizeAnovaFun.power_analysisAnovaFun.sample_sizeAnovaFun.simulate_dataAnovaFun.sphericityAnovaFun.sphericity_checkAnovaFun.sphericity_correctionAnovaFun.to_dictAnovaFun.to_fields_dictAnovaFun.to_makie_dictAnovaFun.to_makie_dictAnovaFun.to_makie_dictAnovaFun.tstatAnovaFun.validate_anova_inputsAnovaFun.within_correlation_matrixAnovaFun.within_factorsAnovaFun.@minimal_warning
Types
AnovaFun.AnovaResult — Type
AnovaResultResults from an ANOVA analysis.
Fields
data::DataFrame: Original data used for analysis (in long format)dv::Symbol: Dependent variable column nameid::Symbol: Subject/participant identifier column nametable::DataFrame: ANOVA table with test statistics. Columns include: Effect, DFn, DFd, SSn, SSd, MSE, F, p, sig, and optionally ε (epsilon), η², η²ₚ, ω²design::DesignInfo: Design metadata containing type (:between,:within, or:mixed), factors, and number of subjectsmodel: Fitted linear model (GLM.TableRegressionModel) for diagnostics. Usemodel(result)to access GLM functions likeresiduals(),fitted(),coef(), etc.
Accessor Functions
Use these functions to extract information from an AnovaResult:
factors(result): Get all factors (between and within)between_factors(result): Get between-subjects factorswithin_factors(result): Get within-subjects factorsn_id(result): Get number of subjectsn_effects(result): Get number of effects (excluding Intercept)design_type(result): Get design type (:between,:within, or:mixed)model(result): Get fitted model
Access data directly using fields:
result.data: Get original dataresult.dv: Get dependent variable nameresult.id: Get subject identifier name
Examples
result = anova(data, :dv, :id, within=[:time])
result.table # Access ANOVA table
factors(result) # Get all factors
design_type(result) # Get design typeAnovaFun.AxisKwargs — Type
Axis customization (prefix: axis_). Known custom fields are struct fields; all other axis_* kwargs go to makie_attrs and are forwarded directly to Makie.Axis().
AnovaFun.BarKwargs — Type
Bar plot customization (prefix: bar_).
AnovaFun.BoxplotKwargs — Type
Boxplot customization (prefix: boxplot_).
AnovaFun.DesignInfo — Type
DesignInfoStores info about the ANOVA design.
Fields
type::Symbol: Design type. Options::between(between-subjects only),:within(within-subjects/repeated measures only), or:mixed(combination of both)between_factors::Vector{Symbol}: Vector of between-subjects factor nameswithin_factors::Vector{Symbol}: Vector of within-subjects (repeated measures) factor namesn_id::Int: Number of unique subjects/participants in the design
Examples
result = anova(data, :dv, :id, between=[:group])
design_type(result) # Returns :between
between_factors(result) # Returns [:group]
within_factors(result) # Returns []
n_id(result) # Returns number of subjectsAnovaFun.EmmeansResult — Type
EmmeansResultResults from estimated marginal means computation.
Fields
means::DataFrame: Marginal means table with columns:Effect: Name of the effect (e.g., "time", "time × condition")Level: Level combination (e.g., "T1" or "T1, Condition1")N: Number of subjects contributing to this meanMean: Estimated marginal meanSD: Standard deviationSE: Standard error of the meanLower: Lower bound of confidence intervalUpper: Upper bound of confidence interval
anova::AnovaResult: The original ANOVA result object used to compute the meanslevel::Float64: Confidence level used for intervals (e.g., 0.95 for 95% CI)group::Union{Vector{Symbol}, Nothing}: Grouping factors (if specified viagroupparameter)
Note: The original data can be accessed via result.anova.data.
Examples
result = anova(data, :dv, :id, within=[:time])
em = emmeans(result)
em.means # Access marginal means table
em.level # Get confidence level (e.g., 0.95)
em.anova # Access original ANOVA result
em = emmeans(result, by=[:time, :condition], group=:condition) # Grouped displayAnovaFun.ErrorbarKwargs — Type
Error bar customization (prefix: errorbar_).
AnovaFun.FacetContext — Type
Facet context bundling common parameters for plot functions. Dramatically reduces parameter lists from 8+ params down to 3-4.
AnovaFun.FacetGrid — Type
Manages a grid of axes for faceted plots.
AnovaFun.FacetSpec — Type
Facet specification struct. Specifies how to facet the plot.
AnovaFun.FigureKwargs — Type
Figure customization (prefix: figure_). Known custom fields are struct fields; all other figure_* kwargs go to makie_attrs.
AnovaFun.IndividualDataKwargs — Type
Individual data point/line customization (prefix: individual_data_).
AnovaFun.JitterKwargs — Type
Jitter customization (prefix: jitter_).
AnovaFun.LayoutKwargs — Type
Layout and figure sizing (prefix: layout_).
AnovaFun.LegendKwargs — Type
Legend customization (prefix: legend_). Known custom fields are struct fields; all other legend_* kwargs go to makie_attrs. The top-level legend=false kwarg maps to show=false.
AnovaFun.PairwiseResult — Type
PairwiseResultResults from pairwise comparisons computation.
Fields
table::DataFrame: Pairwise comparisons table with columns:Effect: Name of the effect being comparedContrast: Description of the comparison (e.g., "Level1 - Level2")Estimate: Mean differenceSE: Standard error of the differencedf: Degrees of freedomt: t-statisticp: Unadjusted p-valuep_adj: Adjusted p-value (if adjustment method specified)Lower: Lower bound of confidence intervalUpper: Upper bound of confidence interval
Examples
result = anova(data, :dv, :id, within=[:time])
em = emmeans(result)
pw = pairwise(em)
pw.table # Access pairwise comparisons tableAnovaFun.PlotConfig — Type
PlotConfigBundle of all typed kwarg structs for the AnovaFun plotting system. Construct from flat kwargs via PlotConfig(; violin_color=:red, axis_ylabel="Y", ...).
AnovaFun.PlotConfig — Method
PlotConfig(; kwargs...)Construct a PlotConfig from flat keyword arguments. Kwargs are routed to the appropriate struct by prefix (e.g., violin_color → ViolinKwargs.color).
Throws ArgumentError for unrecognized kwargs (catches typos like violin_colr).
AnovaFun.PlotPanelSpec — Type
Internal struct to hold plot specification for a single panel.
AnovaFun.PowerResult — Type
PowerResultResults from a power analysis.
Fields
power::DataFrame: Power estimates for each effect with columns: n, Effect, Power, EffectSizepairwise::Union{DataFrame, Nothing}: Power and effect sizes for pairwise comparisons (columns: Comparison, n, power, effect_size)between::Union{Dict{Symbol, Vector{String}}, Nothing}: Between-subjects factors and their levelswithin::Union{Dict{Symbol, Vector{String}}, Nothing}: Within-subjects factors and their levelsn_sims::Union{Int, Nothing}: Number of simulations (if simulation method)alpha::Float64: Significance level used
Examples
using AnovaFun
result = power_analysis(40,
between=Dict(:voice => [:human, :robot]),
within=Dict(:emotion => [:cheerful, :sad]),
mu=[1.03, 1.41, 0.98, 1.01],
sd=1.03,
r=0.8)
result.power # Access power estimates and effect sizes DataFrame
result.power.n # Access sample size from the DataFrame
result.between # Access between-subjects factors
result.within # Access within-subjects factorsAnovaFun.RaincloudComponentSpec — Type
Specification for rendering one side/group of a raincloud plot. Bundles all parameters needed to render violin + boxplot + points.
AnovaFun.RaincloudKwargs — Type
Raincloud plot customization (prefix: raincloud_). Fields prefixed with x2x2_ map to user kwargs raincloud_2x2_*.
AnovaFun.SampleSizeResult — Type
SampleSizeResultResults from a sample size calculation.
Fields
power::DataFrame: Power estimates for each effect at the recommended sample size (columns: n, Effect, Power, EffectSize)results::DataFrame: DataFrame with columnsnand one column per effect/interaction showing power values for each tested sample size
Examples
result = sample_size(80,
within=Dict(:factor1 => [1, 2], :factor2 => [1, 2]),
mu=[1.0, 1.0, 1.0, 2.0],
sd=1.0,
r=0.5)
result.power # Recommended sample size and power for each effect
result.results # Power for all tested sample sizesAnovaFun.ViolinKwargs — Type
Violin plot customization (prefix: violin_).
AnovaFun.YLimKwargs — Type
Y-axis limit calculation (prefix: ylim_).
Functions
AnovaFun.aggregate — Method
aggregate(data, dv, id, within, between)Aggregate data to cell means per subject and condition combination. This collapses the data to one value per subject × condition for ANOVA calculations.
Arguments
data::AbstractDataFrame: Input datadv::Symbol: Dependent variable nameid::Symbol: Subject identifier namewithin::Union{AbstractVector{Symbol}, Nothing}: Within-subjects factorsbetween::Union{AbstractVector{Symbol}, Nothing}: Between-subjects factors
Returns
DataFrame: Aggregated data with one row per subject × condition combination
AnovaFun.all_factors — Method
all_factors(design::DesignInfo)
all_factors(result::AnovaResult)Get all factors in canonical order (between factors first, then within factors).
Arguments
design::DesignInfo: Design informationresult::AnovaResult: ANOVA result object (convenience overload, equivalent tofactors(result))
Returns
A Vector{Symbol} containing all factors in order: between factors followed by within factors.
AnovaFun.anova — Method
anova(data, dv, id; within=nothing, between=nothing, correction=:none, effect_size=:pes)Perform ANOVA on factorial designs including repeated measures (within-subjects), between-subjects, and mixed designs.
Arguments
data::AbstractDataFrame: DataFrame containing the data in long format (one row per observation)dv::Symbol: Symbol naming the dependent variable columnid::Symbol: Symbol naming the subject/participant identifier columnwithin::Union{AbstractVector{Symbol}, Nothing}: Vector of Symbols naming within-subjects (repeated measures) factors (default:nothing)between::Union{AbstractVector{Symbol}, Nothing}: Vector of Symbols naming between-subjects factors (default:nothing)correction::Symbol: Sphericity correction type for within-subjects effects. Options::none(default),:GG(Greenhouse-Geisser), or:HF(Huynh-Feldt). When not:none, addsε(epsilon) column and adjusts degrees of freedom and p-values in the ANOVA table.effect_size::Symbol: Effect size to include. Options::none(no effect sizes),:es(eta squared, η²),:pes(partial eta squared, η²ₚ, default),:os(omega squared, ω²)
Returns
An AnovaResult object containing:
table::DataFrame: ANOVA table with columns: Effect, DFn, DFd, SSn, SSd, MSE, F, p, sig, and optionally ε (epsilon), η², η²ₚ, ω²design::DesignInfo: Design metadata (type::between,:within, or:mixed, factors, number of subjects)model: Fitted linear model (GLM.TableRegressionModel) for diagnostics (residuals, fitted values, coefficients, etc.)data::DataFrame: Original data used for analysisdv::Symbol: Dependent variable nameid::Symbol: Subject identifier name
Examples
# Between-subjects ANOVA
result = anova(data, :dv, :id, between=[:group])
# Within-subjects (repeated measures) ANOVA
result = anova(data, :dv, :id, within=[:time])
# With Greenhouse-Geisser correction for sphericity
result = anova(data, :dv, :id, within=[:time], correction=:GG)
# Mixed design
result = anova(data, :dv, :id, between=[:group], within=[:time])
# With omega squared effect size
result = anova(data, :dv, :id, within=[:time], effect_size=:os)Notes
- Data must be in long format with one row per observation
- At least one factor (within or between) must be specified
- For within-subjects designs, sphericity correction is recommended when factors have more than 2 levels
AnovaFun.anova_table — Method
anova_table(result::AnovaResult; backend=:text, include_intercept=false, include_ss=false, include_mse=false, include_es=true, include_sig=true, title="ANOVA Table", io=stdout)Print an ANOVA table using PrettyTables.
Arguments
result::AnovaResult: AnAnovaResultobjectbackend::Symbol: Output format. Options::markdown,:latex,:text(default::text)include_intercept::Bool: Whether to include the Intercept row (default:false)include_ss::Bool: Whether to include sum of squares columns (default:false)include_mse::Bool: Whether to include MSE column (default:false)include_es::Bool: Whether to include effect size columns (default:true)include_sig::Bool: Whether to include significance column (default:true)title::String: Table title (default:"ANOVA Table")io::IO: Output stream (default:stdout)
Returns
Nothing (prints to io)
Examples
result = anova(data, :dv, :id, within=[:time])
anova_table(result, backend=:markdown)
anova_table(result, backend=:latex)
anova_table(result, backend=:text)
# Minimal table
anova_table(result, include_ss=false, include_mse=false, include_es=false)AnovaFun.between_factors — Method
between_factors(result::AnovaResult)Get between-subjects factors.
Arguments
result::AnovaResult: ANOVA result object
Returns
A Vector{Symbol} containing between-subjects factor names.
Examples
result = anova(data, :dv, :id, between=[:group])
between_factors(result) # Returns [:group]AnovaFun.check_homogeneity — Method
check_homogeneity(result::AnovaResult; center::Function=mean)Levene's test for homogeneity of variance (equal variances across groups).
For between-subjects designs, tests whether variances are equal across groups defined by between-subjects factors. For mixed designs, tests are performed on the between-subjects grouping factors.
Arguments
result::AnovaResult: ANOVA result objectcenter::Function: Centering function:meanormedian
Returns
An AnovaResult object (same as anova()), containing:
table: ANOVA table with test statisticsdesign: Design informationmodel: Fitted linear model- Other accessor methods (see
anova()documentation)
The main effect in the table (group) tests variance homogeneity across all group combinations.
Examples
result = anova(data, :dv, :subject, between=[:group])
check_homogeneity(result) AnovaFun.ci — Method
ci(lower::Real, upper::Real; format::Symbol=:markdown)
ci(result::EmmeansResult, effect::String, level::String; format::Symbol=:markdown)Format confidence interval string according to APA style.
Arguments
lower::Real: Lower bound of the confidence interval (for direct call)upper::Real: Upper bound of the confidence interval (for direct call)result::EmmeansResult: Emmeans result object (for method with result)effect::String: Name of the effect (for method with result)level::String: Level of the effect (for method with result)format::Symbol: Output format. Options::markdown(default),:latex,:text
Returns
A formatted string with the confidence interval (e.g., "95% CI [20.15, 30.71]" in markdown format).
Examples
ci(20.15, 30.71) # Returns "*95% CI* [20.15, 30.71]"
# From emmeans result
result = anova(data, :dv, :id, within=[:time])
em = emmeans(result)
ci(em, "time", "T1") # Returns "*95% CI* [20.15, 30.71]"AnovaFun.design_type — Method
design_type(result::AnovaResult)Get the design type.
Arguments
result::AnovaResult: ANOVA result object
Returns
A Symbol indicating the design type: :between, :within, or :mixed.
Examples
result = anova(data, :dv, :id, between=[:group])
design_type(result) # Returns :between
result = anova(data, :dv, :id, within=[:time])
design_type(result) # Returns :within
result = anova(data, :dv, :id, between=[:group], within=[:time])
design_type(result) # Returns :mixedAnovaFun.emmeans — Method
emmeans(result::AnovaResult; by=nothing, group=nothing, level=0.95, adjust=:none)Compute estimated marginal means from an ANOVA result. This method uses the data stored in the result object.
Arguments
result::AnovaResult: AnAnovaResultobject fromanova()by::Union{Symbol, Vector{Symbol}, Nothing}: Effect(s) to compute marginal means for.nothing(default): Compute marginal means for all effects (all factors and their interactions)Symbol: Compute marginal means for a single factor (e.g.,:time)Vector{Symbol}: Compute marginal means for an interaction (e.g.,[:time, :condition])
group::Union{Symbol, Vector{Symbol}, Nothing}: Factor(s) to group results by for display.nothing(default): Show all results in a single tableSymbolorVector{Symbol}: Group results by these factors (must be a subset ofbyfactors)- When
groupis specified, results are displayed in separate sections for each group combination
level::Float64: Confidence level for confidence intervals (default: 0.95 for 95% CI)adjust::Symbol: Method for confidence interval adjustment. Options::none(default),:bonferroni, or:sidak
Returns
An EmmeansResult object containing:
means::DataFrame: Marginal means table with columns Effect, Level, N, Mean, SD, SE, Lower, Upperanova::AnovaResult: The original ANOVA result objectlevel::Float64: Confidence level used for intervalsgroup::Union{Vector{Symbol}, Nothing}: Grouping factors (if specified)
Note: The original data can be accessed via result.anova.data.
Examples
result = anova(data, :dv, :id, within=[:time])
em = emmeans(result) # all effects
em = emmeans(result, by=:time) # single factor
em = emmeans(result, by=[:time, :condition]) # interaction
em = emmeans(result, by=[:time, :condition], group=:condition) # grouped by condition
em = emmeans(result, by=:time, adjust=:bonferroni) # with correctionAnovaFun.emmeans_table — Method
emmeans_table(result::EmmeansResult; backend=:text, title="Estimated Marginal Means", io=stdout)Print an estimated marginal means table using PrettyTables.
Arguments
result::EmmeansResult: AnEmmeansResultobjectbackend::Symbol: Output format. Options::markdown,:latex,:text(default::text)title::String: Table title (default:"Estimated Marginal Means")io::IO: Output stream (default:stdout)
Returns
Nothing (prints to io)
Examples
result = anova(data, :dv, :id, within=[:time])
em = emmeans(result)
emmeans_table(em, backend=:markdown)
emmeans_table(em, backend=:latex)
emmeans_table(em, backend=:text)AnovaFun.errorbar_limits! — Method
errorbar_limits!(result, errorbars)Add error bar distances from mean to the EmmeansResult (mutating).
Adds an error column to result.means with the symmetrical distance from the mean (error bars extend Mean ± error).
Arguments
result::EmmeansResult: The emmeans result (will be mutated)errorbars::Symbol: Error bar type (:none,:SE,:CI,:withinSE,:withinCI)
Returns
nothing(mutatesresult.meansin place)
AnovaFun.f — Method
f(result::AnovaResult, effect::String; format::Symbol=:markdown)Format F-statistic string according to APA style.
AnovaFun.factors — Method
factors(result::AnovaResult)Get all factors in the design (both between and within).
Arguments
result::AnovaResult: ANOVA result object
Returns
A Vector{Symbol} containing all factor names (between-subjects and within-subjects combined).
Examples
result = anova(data, :dv, :id, between=[:group], within=[:time])
factors(result) # Returns [:group, :time]AnovaFun.fstat — Method
fstat(result::AnovaResult, effect::String; format::Symbol=:markdown)Return full APA formatted statistics string for an ANOVA effect.
Combines F-statistic, p-value, effect size, and sphericity correction (if applicable) into a single formatted string.
Arguments
result::AnovaResult: ANOVA result objecteffect::String: Name of the effect from the ANOVA tableformat::Symbol: Output format. Options::markdown(default),:latex,:text
Returns
A formatted string containing F-statistic, p-value, effect size, and sphericity correction (if applicable), separated by commas.
Examples
result = anova(data, :dv, :subject, within=[:time], correction=:GG)
fstat(result, "time", format=:markdown)
# Returns: "*F*(2, 18) = 5.43, *p* = .012, *η²ₚ* = 0.38, *ε* = 0.85" (example)AnovaFun.independent_ttest — Method
independent_ttest(x::AbstractVector, y::AbstractVector; tail::Symbol = :both)Compute independent sample t-test with degrees of freedom, t-statistic, and p-value. Assumes equal variances (standard independent t-test). Also returns Cohen's d (reported as d).
Arguments
x::AbstractVector: First group data (must have at least 2 observations)y::AbstractVector: Second group data (must have at least 2 observations)tail::Symbol: Type of test -:both(two-tailed, default),:left(one-tailed, A < B), or:right(one-tailed, A > B)
Returns
- Named tuple with fields:
df: degrees of freedomt: t-statisticp: p-value (returnsNaNiftisNaN/Inf)d: Cohen's d using pooled SD
AnovaFun.independent_ttest — Method
independent_ttest(df::DataFrame, col::Symbol; by::Symbol, levels = nothing, tail::Symbol = :both)Convenience method for independent t-test from a DataFrame.
Splits df by the by column into exactly two groups and runs an independent t-test on the values in col.
Arguments
df::DataFrame: DataFrame containing the datacol::Symbol: Column to testby::Symbol: Grouping column (must have exactly 2 unique values, or uselevels)levels: Optional vector of 2 values to select frombycolumn (useful when >2 groups exist)tail::Symbol: Type of test (:both,:left, or:right)
Examples
# Auto-detect two groups
independent_ttest(df, :dv_col, by = :grouping_col)
# Specify which two groups to compare
independent_ttest(df, :dv_col, by = :grouping_col, levels = [1, 2])AnovaFun.m — Method
m(result::EmmeansResult, effect::String, level::String; unit::String="", format::Symbol=:markdown)Format marginal mean string according to APA style.
Arguments
result::EmmeansResult: Emmeans result objecteffect::String: Name of the effectlevel::String: Level of the effect (e.g., "Level1" or "Level1, Level2" for interactions)unit::String: Optional unit to append to the mean value (default:"")format::Symbol: Output format. Options::markdown(default),:latex,:text
Returns
A formatted string with the mean value (e.g., "M = 25.43" in markdown format).
Examples
result = anova(data, :dv, :id, within=[:time])
em = emmeans(result)
m(em, "time", "T1") # Returns "*M* = 25.43"
m(em, "time", "T1", unit="ms") # Returns "*M* = 25.43 ms"AnovaFun.m_ci — Method
m_ci(result::EmmeansResult, effect::String, level::String; unit::String="", format::Symbol=:markdown)Format marginal mean with confidence interval string according to APA style.
This is a convenience function that combines m() and ci() into a single formatted string.
Arguments
result::EmmeansResult: Emmeans result objecteffect::String: Name of the effectlevel::String: Level of the effect (e.g., "Level1" or "Level1, Level2" for interactions)unit::String: Optional unit to append to the mean value (default:"")format::Symbol: Output format. Options::markdown(default),:latex,:text
Returns
A formatted string combining mean and confidence interval (e.g., "M = 25.43, 95% CI [20.15, 30.71]" in markdown format).
Examples
result = anova(data, :dv, :id, within=[:time])
em = emmeans(result)
m_ci(em, "time", "T1") # Returns "*M* = 25.43, *95% CI* [20.15, 30.71]" AnovaFun.model — Method
model(result::AnovaResult)Get the fitted linear model (always available).
Use this to access GLM functionality directly, e.g.:
GLM.residuals(model(result))GLM.fitted(model(result))GLM.coef(model(result))GLM.vcov(model(result))GLM.stderror(model(result))GLM.r2(model(result))GLM.adjr2(model(result))
AnovaFun.n_effects — Method
n_effects(result::AnovaResult)Get number of effects in the ANOVA table (excluding Intercept).
Arguments
result::AnovaResult: ANOVA result object
Returns
An Int representing the number of effects (main effects and interactions, excluding Intercept).
Examples
result = anova(data, :dv, :id, between=[:group], within=[:time])
n_effects(result) # Returns number of effects (e.g., 3 for group, time, group×time)AnovaFun.n_id — Method
n_id(result::AnovaResult)Get number of subjects/participants in the design.
Arguments
result::AnovaResult: ANOVA result object
Returns
An Int representing the number of unique subjects.
Examples
result = anova(data, :dv, :id, within=[:time])
n_id(result) # Returns number of subjects (e.g., 20)AnovaFun.p — Method
p(p::Real; format::Symbol=:markdown)
p(result::AnovaResult, effect::String; format::Symbol=:markdown)Format a p-value string according to APA style. Supported formats: :markdown, :latex, :text.
AnovaFun.paired_ttest — Method
paired_ttest(x::AbstractVector, y::AbstractVector; tail::Symbol = :both)Compute paired t-test with degrees of freedom, t-statistic, and p-value. Also returns Cohen's dz (reported as dz).
Arguments
x::AbstractVector: First condition data (must have same length as y)y::AbstractVector: Second condition data (must have same length as x)tail::Symbol: Type of test -:both(two-tailed, default),:left(one-tailed, A < B), or:right(one-tailed, A > B)
Returns
- Named tuple with fields:
df: degrees of freedomt: t-statisticp: p-value (returnsNaNiftisNaN/Inf)dz: Cohen's dz computed as mean(diff) / std(diff)
AnovaFun.paired_ttest — Method
paired_ttest(df::DataFrame, col::Symbol; by::Symbol, levels = nothing, tail::Symbol = :both)Convenience method for paired t-test from a DataFrame.
Splits df by the by column into exactly two groups and runs a paired t-test on the values in col.
Arguments
df::DataFrame: DataFrame containing the datacol::Symbol: Column to testby::Symbol: Grouping column (must have exactly 2 unique values, or uselevels)levels: Optional vector of 2 values to select frombycolumn (useful when >2 groups exist)tail::Symbol: Type of test (:both,:left, or:right)
Examples
# Auto-detect two groups
paired_ttest(df, :dv_col, by = :grouping_col)
# Specify which two groups to compare
paired_ttest(df, :dv_col, by = :grouping_col, levels = [1, 2])AnovaFun.pairwise — Method
pairwise(emmeans_result::EmmeansResult; simple=nothing, adjust=:none)Compute pairwise comparisons from an emmeans result. Matches R's pairs() function from the emmeans package.
Arguments
emmeans_result::EmmeansResult:EmmeansResultobject fromemmeans()simple::Union{Symbol, Nothing}: Simple contrasts specification (default:nothing):nothing: All pairwise comparisons across all cell means (like R'spairs(em)):each: Simple contrasts for each factor within levels of other factors:FactorName: Simple contrasts for specified factor within levels of other factors
adjust::Symbol: Method for p-value and confidence interval adjustment. Options::none(default),:bonferroni, or:sidak
Returns
A PairwiseResult object containing:
table::DataFrame: Pairwise comparison results with columns:Context: Conditioning context (e.g., "CurrentCongruency = Congruent") for simple contrastsEffect: Name of the effect being comparedContrast: Description of the comparison (e.g., "Level1 - Level2")Estimate: Mean differenceSE: Standard error of the differencedf: Degrees of freedomt: t-statisticp: Unadjusted p-valuep_adj: Adjusted p-value (if adjustment method specified)Lower: Lower bound of confidence intervalUpper: Upper bound of confidence interval
The confidence level is taken from emmeans_result.level.
Examples
result = anova(data, :dv, :id, within=[:A, :B])
em = emmeans(result, by=[:A, :B])
# All pairwise comparisons across all cell means
pw = pairwise(em)
# Simple contrasts for factor A within levels of B
pw = pairwise(em, simple=:A)
# Simple contrasts for each factor
pw = pairwise(em, simple=:each)
# With p-value correction
pw = pairwise(em, adjust=:bonferroni)AnovaFun.pairwise_table — Method
pairwise_table(result::PairwiseResult; backend=:text, title="Pairwise Comparisons", io=stdout)Print a pairwise comparisons table using PrettyTables.
Arguments
result::PairwiseResult: APairwiseResultobjectbackend::Symbol: Output format. Options::markdown,:latex,:text(default::text)title::String: Table title (default:"Pairwise Comparisons")io::IO: Output stream (default:stdout)
Returns
Nothing (prints to io)
Examples
result = anova(data, :dv, :id, within=[:time])
em = emmeans(result)
pw = pairwise(em)
pairwise_table(pw, backend=:markdown)AnovaFun.plot_anova! — Method
plot_anova!(position, result; x_grouping, y_grouping=nothing, ...)Mutating variant of plot_anova that renders into an existing figure position, enabling multiple plots to be combined in a single Figure.
Arguments
position: A grid position in an existing figure, e.g.fig[1, 1]orfig[1, 2]- All remaining arguments are identical to
plot_anova
Returns
The parent Figure (already provided by the caller, returned for convenience).
Examples
fig = Figure(size = (1600, 700))
plot_anova!(fig[1, 1], result_rt, x_grouping=:pola, y_grouping=:comp,
plot_type=:raincloud_custom_2x2, axis_ylabel="RT [ms]")
plot_anova!(fig[1, 2], result_er, x_grouping=:pola, y_grouping=:comp,
plot_type=:raincloud_custom_2x2, axis_ylabel="Error Rate [%]")
save("combined.png", fig)AnovaFun.plot_sample_size — Method
plot_sample_size(result::SampleSizeResult; target_power=nothing, kwargs...)Plot power curves for sample size analysis.
Shows how power changes with sample size for each effect. Includes a horizontal line at the target power and a vertical line at the recommended N.
Arguments
result::SampleSizeResult: Result fromsample_size()target_power::Union{Real, Nothing}: Target power level (0-100). Ifnothing, inferred from minimum power in resultfigure_size::Tuple{Int,Int}: Figure size in pixels (default: (800, 600))theme::Union{Theme, Nothing}: Makie theme for customization
Returns
A Makie.Figure object that auto-displays in the REPL.
Examples
result = sample_size(80, ...)
plot_sample_size(result) # Basic plotAnovaFun.power_analysis — Method
power_analysis(n; within=nothing, between=nothing, mu, sd, r=nothing, n_sims=1000, alpha=0.05, pairwise=false)Perform power analysis for an ANOVA design using simulation.
Arguments
n::Int: Number of subjects/participants (positional argument)- For between-subjects designs: number of subjects per group
- For within-subjects designs: total number of subjects
- For mixed designs: number of subjects per between-subjects group
within::Union{Dict{Symbol, Vector}, Nothing}: Dictionary mapping within-subjects factor names to level labelsbetween::Union{Dict{Symbol, Vector}, Nothing}: Dictionary mapping between-subjects factor names to level labelsmu::Union{Real, Vector{<:Real}}: Cell means. Single value for all cells, or vector (one per cell, matching cell order)sd::Union{Real, Vector{<:Real}}: Standard deviation. Single value for all cells, or vector (one per cell, matchingmuorder)r::Union{Real, Vector{<:Real}, Nothing}: Correlation for within-subjects factors (default: nothing)n_sims::Int: Number of simulations to run (default: 1000)alpha::Float64: Significance level (default: 0.05)pairwise::Bool: Whether to compute pairwise comparison power (default: false)
Returns
A PowerResult object containing:
- Power estimates and effect sizes (partial eta-squared) for each ANOVA effect
- Power and effect sizes (Cohen's d) for pairwise comparisons (all pairwise comparisons across all cell means), if
pairwise=true
Examples
# Within-subjects design
result = power_analysis(20,
within=Dict(:factor1 => [1, 2], :factor2 => [1, 2]),
mu=[1.1, 1.2, 1.6, 1.8],
sd=1.0,
r=0.5,
n_sims=1000)
result.power # View power estimates and effect sizes
# Mixed design
result = power_analysis(40,
between=Dict(:voice => [:human, :robot]),
within=Dict(:emotion => [:cheerful, :sad]),
mu=[1.03, 1.41, 0.98, 1.01],
sd=1.03,
r=0.8)AnovaFun.sample_size — Method
sample_size(; target_power=80, within=nothing, between=nothing, mu, sd, r=nothing, method=:binary, n_sims=1000, alpha=0.05, min_n=5, max_n=500, step=1, n_anchors=10)Estimate the required sample size to achieve a target power level using simulation.
Arguments
target_power::Real: Target power level (e.g., 80 for 80% power) on 0-100 scale (default: 80)within::Union{Dict{Symbol, Vector}, Nothing}: Dictionary mapping within-subjects factor names to level labelsbetween::Union{Dict{Symbol, Vector}, Nothing}: Dictionary mapping between-subjects factor names to level labelsmu::Union{Real, Vector{<:Real}}: Cell means. Single value for all cells, or vector (one per cell, matching cell order)sd::Union{Real, Vector{<:Real}}: Standard deviation. Single value for all cells, or vector (one per cell, matchingmuorder)r::Union{Real, Vector{<:Real}, Nothing}: Correlation for within-subjects factors (default: nothing)method::Symbol: Search method. Options::binary(default): Binary search with independent per-effect search and anchor points:sequential: Sequential search from minn to maxn (slower, dense results for plotting)
step::Int: Step size for sequential search (default: 1). Use larger values (e.g., 5-10) for faster sequential searchn_anchors::Int: Number of evenly-spaced anchor points to test initially (binary method only, default: 10). Higher values give smoother plots but take longern_sims::Int: Number of simulations per sample size tested (default: 1000)alpha::Float64: Significance level (default: 0.05)min_n::Int: Minimum sample size to test (default: 5)- For between-subjects designs: minimum number of subjects per group
- For within-subjects designs: minimum total number of subjects
- For mixed designs: minimum number of subjects per between-subjects group
max_n::Int: Maximum sample size to test (default: 500)- For between-subjects designs: maximum number of subjects per group
- For within-subjects designs: maximum total number of subjects
- For mixed designs: maximum number of subjects per between-subjects group
Returns
A SampleSizeResult object containing:
power::DataFrame: Power estimates for each effect at the recommended sample size (columns: n, Effect, Power, EffectSize)nrepresents per-group sample size for between-subjects designs, total sample size for within-subjects designs
results::DataFrame: DataFrame with columnsnand one column per effect/interaction showing power values for each tested sample sizenrepresents per-group sample size for between-subjects designs, total sample size for within-subjects designs
Examples
# Within-subjects design
result = sample_size(target_power=80, # 80% power
within=Dict(:factor1 => [1, 2], :factor2 => [1, 2]),
mu=[1.0, 1.0, 1.0, 2.0],
sd=1.0,
r=0.5,
n_sims=100,
method=:binary)
# Sequential search with larger step size (faster, coarser)
result = sample_size(target_power=80, # 80% power
within=Dict(:factor1 => [1, 2], :factor2 => [1, 2]),
mu=[1.0, 1.0, 1.0, 2.0],
sd=1.0,
r=0.5,
method=:sequential,
min_n=10,
max_n=100,
step=5) # Test every 5th sample size for speedAnovaFun.simulate_data — Method
simulate_data(n; within=nothing, between=nothing, mu, sd, r=nothing)Generate a simulated DataFrame with known properties for ANOVA analysis.
This function creates a DataFrame with the specified design structure, means, standard deviations, and correlations. The design is specified using dictionaries mapping factor names to their level labels, making it consistent with the anova function signature.
Arguments
n::Int: Number of subjects/participants (positional argument)- For between-subjects designs: number of subjects per group
- For within-subjects designs: total number of subjects
- For mixed designs: number of subjects per between-subjects group
within::Union{Dict{Symbol, Vector}, Nothing}: Dictionary mapping within-subjects factor names to level labels. Example:Dict(:factor1 => [:a1, :a2], :factor2 => [:b1, :b2])between::Union{Dict{Symbol, Vector}, Nothing}: Dictionary mapping between-subjects factor names to level labels. Example:Dict(:group => [:control, :treatment])mu::Union{Real, Vector{<:Real}}: Cell means in cell order (all combinations of factors)sd::Union{Real, Vector{<:Real}}: Standard deviation. Single value for all cells, or vector (one per cell, matchingmuorder)r::Union{Real, Vector{<:Real}, Nothing}: Correlation for within-subjects factors (compound symmetry). Default:nothing(uses 0.0)
Returns
A DataFrame with columns in order:
id: Subject/participant ID (first column)- Factor columns: One column per factor with level labels (middle columns)
dv: Dependent variable values (last column)
Examples
# Generate data for a 2×2 within-subjects design
data = simulate_data(20,
within = Dict(:factor1 => [:a1, :a2], :factor2 => [:b1, :b2]),
mu = [1.0, 1.0, 1.0, 2.0],
sd = 1.0,
r = 0.5)AnovaFun.sphericity — Method
sphericity(result::AnovaResult, effect::String; format::Symbol=:markdown)Format sphericity epsilon (ε) string for an effect.
Returns an empty string if the effect does not have sphericity correction applied (ε = 1.0 or missing).
Arguments
result::AnovaResult: ANOVA result objecteffect::String: Name of the effect from the ANOVA tableformat::Symbol: Output format. Options::markdown(default),:latex,:text
Returns
A formatted string with the epsilon value, or an empty string if no correction was applied.
Examples
result = anova(data, :dv, :subject, within=[:time], correction=:GG)
sphericity(result, "time", format=:markdown) # Returns "*ε* = 0.85" (example)AnovaFun.sphericity_check — Method
sphericity_check(result::AnovaResult)Mauchly's test for sphericity for within-subjects designs with factor with more than two levels.
Tests whether the assumption of sphericity holds in repeated measures ANOVA. Sphericity requires that the variances of the differences between all pairs of within-subject conditions are equal.
Arguments
result::AnovaResult: ANOVA result object
Returns
A DataFrame with columns:
Effect: Name of the within-subjects effectW: Mauchly's W statisticp: p-value
Examples
result = anova(data, :dv, :subject, within=[:time])
sphericity_check(result)AnovaFun.sphericity_correction — Method
sphericity_correction(result::AnovaResult; type::Symbol=:GG)Apply sphericity correction to an existing ANOVA result.
This function applies Greenhouse-Geisser or Huynh-Feldt correction to within-subjects effects in an ANOVA result. This is useful if you want to apply a different correction method than was used initially, or if you want to apply correction to a result that was computed without it.
Arguments
result::AnovaResult: ANOVA result object to apply correction totype::Symbol: Correction type. Options::GG(Greenhouse-Geisser, default) or:HF(Huynh-Feldt)
Returns
A new AnovaResult object with sphericity correction applied. The correction modifies:
ε(epsilon) column: Added or updated with correction factorDFnandDFd: Adjusted by epsilon (may become non-integer)p: Recalculated using corrected degrees of freedomMSE: Recalculated based on correctedDFd
Examples
# Run ANOVA without correction
result = anova(data, :dv, :subject, within=[:time], correction=:none)
result_gg = sphericity_correction(result, type=:GG) # Greenhouse-Geisser correction
result_hf = sphericity_correction(result, type=:HF) # Huynh-Feldt correctionNote
This function requires at least one within-subjects factor. For between-subjects designs, this function will return the result unchanged.
AnovaFun.to_dict — Method
to_dict(config::PlotConfig) → Dict{Symbol,Any}Convert a PlotConfig back to the flat Dict{Symbol,Any} format expected by internal plotting code. Used for backward compatibility during migration.
AnovaFun.to_fields_dict — Method
to_fields_dict(obj; exclude=Set{Symbol}())Convert any kwarg struct to a Dict{Symbol,Any} for splatting into Makie calls. Skips nothing values and the makie_attrs field. Use exclude to skip specific fields.
AnovaFun.to_makie_dict — Method
to_makie_dict(a::AxisKwargs)Convert AxisKwargs to a Dict containing only valid Makie.Axis attributes. Custom fields (xticklabels, xorder, yticks, xlim, ylim) are excluded — they're handled separately.
AnovaFun.to_makie_dict — Method
to_makie_dict(f::FigureKwargs)Convert FigureKwargs to a Dict containing only valid Makie.Figure attributes.
AnovaFun.to_makie_dict — Method
to_makie_dict(l::LegendKwargs; exclude_positioning=false)Convert LegendKwargs to a Dict containing valid Makie.Legend attributes.
AnovaFun.tstat — Method
tstat(result; format::Symbol=:markdown)Return APA-style formatted statistics string for a t-test result.
Accepts a named tuple like the outputs of paired_ttest or independent_ttest, containing:
df,t,p, and eitherdz(paired) ord(independent).
Examples:
res = paired_ttest(x, y)
tstat(res) # "*t*(4) = -3.92, *p* = .017, dz = 1.75"AnovaFun.validate_anova_inputs — Method
validate_anova_inputs(data, dv, id, within, between, correction, effect_size)Centralized validation for all ANOVA inputs. Throws informative errors for invalid inputs.
AnovaFun.within_correlation_matrix — Method
within_correlation_matrix(data::DataFrame)Return the within-subjects correlation matrix for a design from a DataFrame (e.g., from simulate_data).
Data must be in long format (with :id, factor columns, and :dv). It will be converted to wide format internally.
Arguments
data::DataFrame: DataFrame in long format with:id, factor columns, and:dv
Returns
A DataFrame with cell names as row and column names, containing correlation values.
Examples
data = simulate_data(40,
between=Dict(:voice => [:human, :robot]),
within=Dict(:emotion => [:cheerful, :sad]),
mu=[1.03, 1.41, 0.98, 1.01], sd=1.03, r=0.8)
corr = within_correlation_matrix(data)AnovaFun.within_factors — Method
within_factors(result::AnovaResult)Get within-subjects (repeated measures) factors.
Arguments
result::AnovaResult: ANOVA result object
Returns
A Vector{Symbol} containing within-subjects factor names.
Examples
result = anova(data, :dv, :id, within=[:time])
within_factors(result) # Returns [:time]AnovaFun.@minimal_warning — Macro
@minimal_warning(msg)Displays an error message and stops execution without showing a full stacktrace.