diff --git a/src/frontend/fit/fitmeasures/AIC.jl b/src/frontend/fit/fitmeasures/AIC.jl index f26f1f4dc..91bc09810 100644 --- a/src/frontend/fit/fitmeasures/AIC.jl +++ b/src/frontend/fit/fitmeasures/AIC.jl @@ -1,6 +1,9 @@ """ - AIC(sem_fit::SemFit) + AIC(fit::SemFit) -Return the akaike information criterion. +Calculate the *AIC* ([*Akaike information criterion*](https://en.wikipedia.org/wiki/Akaike_information_criterion)). + +# See also +[`fit_measures`](@ref) """ -AIC(sem_fit::SemFit) = minus2ll(sem_fit) + 2nparams(sem_fit) +AIC(fit::SemFit) = minus2ll(fit) + 2nparams(fit) diff --git a/src/frontend/fit/fitmeasures/BIC.jl b/src/frontend/fit/fitmeasures/BIC.jl index 20638f4e4..44190375a 100644 --- a/src/frontend/fit/fitmeasures/BIC.jl +++ b/src/frontend/fit/fitmeasures/BIC.jl @@ -1,6 +1,9 @@ """ - BIC(sem_fit::SemFit) + BIC(fit::SemFit) -Return the bayesian information criterion. +Calculate the *BIC* ([*Bayesian information criterion*](https://en.wikipedia.org/wiki/Bayesian_information_criterion)). + +# See also +[`fit_measures`](@ref) """ -BIC(sem_fit::SemFit) = minus2ll(sem_fit) + log(nsamples(sem_fit)) * nparams(sem_fit) +BIC(fit::SemFit) = minus2ll(fit) + log(nsamples(fit)) * nparams(fit) diff --git a/src/frontend/fit/fitmeasures/RMSEA.jl b/src/frontend/fit/fitmeasures/RMSEA.jl index f9dae84ed..890a7ed53 100644 --- a/src/frontend/fit/fitmeasures/RMSEA.jl +++ b/src/frontend/fit/fitmeasures/RMSEA.jl @@ -1,7 +1,23 @@ """ RMSEA(fit::SemFit) -Return the RMSEA. +Calculate the RMSEA ([*Root Mean Squared Error of Approximation*](https://meth.psychopen.eu/index.php/meth/article/download/2333/2333.html?inline=1#sec1)). + +Uses the formula +```math +\\mathrm{RMSEA} = \\sqrt{\\frac{\\chi^2 - N_{\\mathrm{df}}}{N_{\\mathrm{obs}} * N_{\\mathrm{df}}}}, +``` +where *χ²* is the chi-squared statistic, ``N_{\\mathrm{df}}`` is the degrees of freedom, +and ``N_{\\mathrm{obs}}`` is the (corrected) number of observations +for the SEM model. + +# See also +[`fit_measures`](@ref), [`χ²`](@ref), [`dof`](@ref) + +# Extended help + +For multigroup models, the correction proposed by J.H. Steiger is applied +(see [Steiger, J. H. (1998). *A note on multiple sample extensions of the RMSEA fit index*](https://doi.org/10.1080/10705519809540115)). """ function RMSEA end diff --git a/src/frontend/fit/fitmeasures/chi2.jl b/src/frontend/fit/fitmeasures/chi2.jl index dc19467fc..d1bf8f926 100644 --- a/src/frontend/fit/fitmeasures/chi2.jl +++ b/src/frontend/fit/fitmeasures/chi2.jl @@ -1,7 +1,14 @@ """ χ²(fit::SemFit) -Return the χ² value. +Calculate the *χ²* (*chi-square*) value for the `fit`. + +The *χ²* is a test statistic for the SEM goodness-of-fit. +It compares the *implied* covariance matrix of the SEM model +with the *observed* covariance matrix. + +# See also +[`fit_measures`](@ref) """ χ²(fit::SemFit) = χ²(fit, fit.model) diff --git a/src/frontend/fit/fitmeasures/dof.jl b/src/frontend/fit/fitmeasures/dof.jl index 3df49d89d..0e051d02a 100644 --- a/src/frontend/fit/fitmeasures/dof.jl +++ b/src/frontend/fit/fitmeasures/dof.jl @@ -1,12 +1,20 @@ """ - dof(sem_fit::SemFit) + dof(fit::SemFit) dof(model::AbstractSem) -Return the degrees of freedom. +Get the *degrees of freedom* for the SEM model. + +The *degrees of freedom* for the SEM with *N* observed variables is the difference +between the number of non-redundant elements in the observed covariance matrix +(*½N(N+1)*) and the number of model parameters, *q* ([`nparams(model)`](@ref nparams)). +If the SEM also models the observed means, the formula becomes *½N(N+1) + N - q*. + +# See also +[`fit_measures`](@ref) """ function dof end -dof(sem_fit::SemFit) = dof(sem_fit.model) +dof(fit::SemFit) = dof(fit.model) dof(model::AbstractSem) = n_dp(model) - nparams(model) diff --git a/src/frontend/fit/fitmeasures/fit_measures.jl b/src/frontend/fit/fitmeasures/fit_measures.jl index afdde173b..185b348c0 100644 --- a/src/frontend/fit/fitmeasures/fit_measures.jl +++ b/src/frontend/fit/fitmeasures/fit_measures.jl @@ -1,19 +1,25 @@ -fit_measures(sem_fit) = - fit_measures(sem_fit, nparams, dof, AIC, BIC, RMSEA, χ², p_value, minus2ll) +fit_measures(fit) = fit_measures(fit, nparams, dof, AIC, BIC, RMSEA, χ², p_value, minus2ll) -function fit_measures(sem_fit, args...) - measures = Dict{Symbol, Union{Float64, Missing}}() +fit_measures(fit, measures...) = Dict(Symbol(fn) => fn(fit) for fn in measures) - for arg in args - push!(measures, Symbol(arg) => arg(sem_fit)) - end +""" + fit_measures(fit::SemFit, measures...) -> Dict{Symbol} - return measures -end +Calculate fit measures for the SEM solution. -""" - fit_measures(sem_fit, args...) +The `measures` are the functions that calculate fit measures for a given SEM solution +([`SemFit`](@ref) object). If no `measures` are specified, the default set of measures is used. + +Returns a dictionary of the fit measures, where the keys are the function names. + +# Examples + +```julia +fit_measures(semfit) +fit_measures(semfit, nparams, dof, p_value) +``` -Return a default set of fit measures or the fit measures passed as `args...`. +# See also +[`AIC`](@ref), [`BIC`](@ref), [`RMSEA`](@ref), [`χ²`](@ref), [`p_value`](@ref), [`minus2ll`](@ref) """ -function fit_measures end +fit_measures diff --git a/src/frontend/fit/fitmeasures/minus2ll.jl b/src/frontend/fit/fitmeasures/minus2ll.jl index 9b211fb44..d971e53a7 100644 --- a/src/frontend/fit/fitmeasures/minus2ll.jl +++ b/src/frontend/fit/fitmeasures/minus2ll.jl @@ -1,7 +1,10 @@ """ - minus2ll(sem_fit::SemFit) + minus2ll(fit::SemFit) -Return the negative 2* log likelihood. +Calculate the *-2⋅log(likelihood(fit))*. + +# See also +[`fit_measures`](@ref) """ function minus2ll end diff --git a/src/frontend/fit/fitmeasures/p.jl b/src/frontend/fit/fitmeasures/p.jl index da9bedaf6..50cf7220c 100644 --- a/src/frontend/fit/fitmeasures/p.jl +++ b/src/frontend/fit/fitmeasures/p.jl @@ -1,6 +1,9 @@ """ - p(sem_fit::SemFit) + p_value(fit::SemFit) -Return the p value computed from the χ² test statistic. +Calculate the *p*-value for the *χ²* test statistic. + +# See also +[`fit_measures`](@ref), [`χ²`](@ref) """ -p_value(sem_fit::SemFit) = ccdf(Chisq(dof(sem_fit)), χ²(sem_fit)) +p_value(fit::SemFit) = ccdf(Chisq(dof(fit)), χ²(fit))