R/mod.h.R

Defines functions mod

Documented in mod

# This file is automatically generated, you probably don't want to edit this

modOptions <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
    "modOptions",
    inherit = jmvcore::Options,
    public = list(
        initialize = function(
            dep = NULL,
            mod = NULL,
            pred = NULL,
            estMethod = "standard",
            bootstrap = 1000,
            label = FALSE,
            test = TRUE,
            ci = FALSE,
            ciWidth = 95,
            pathDiagram = FALSE,
            pathDiagramLabel = TRUE,
            pathDiagramEst = TRUE,
            pathDiagramSig = TRUE,
            pathDiagramMainEffect = FALSE,
            simpleSlopeEst = FALSE,
            simpleSlopePlot = FALSE, ...) {

            super$initialize(
                package="medmod",
                name="mod",
                requiresData=TRUE,
                ...)

            private$..dep <- jmvcore::OptionVariable$new(
                "dep",
                dep,
                suggested=list(
                    "continuous"),
                permitted=list(
                    "numeric"))
            private$..mod <- jmvcore::OptionVariable$new(
                "mod",
                mod,
                suggested=list(
                    "continuous"),
                permitted=list(
                    "numeric"))
            private$..pred <- jmvcore::OptionVariable$new(
                "pred",
                pred,
                suggested=list(
                    "continuous"),
                permitted=list(
                    "numeric"))
            private$..estMethod <- jmvcore::OptionList$new(
                "estMethod",
                estMethod,
                options=list(
                    "standard",
                    "bootstrap"),
                default="standard")
            private$..bootstrap <- jmvcore::OptionInteger$new(
                "bootstrap",
                bootstrap,
                min=1,
                default=1000)
            private$..label <- jmvcore::OptionBool$new(
                "label",
                label,
                default=FALSE)
            private$..test <- jmvcore::OptionBool$new(
                "test",
                test,
                default=TRUE)
            private$..ci <- jmvcore::OptionBool$new(
                "ci",
                ci,
                default=FALSE)
            private$..ciWidth <- jmvcore::OptionNumber$new(
                "ciWidth",
                ciWidth,
                min=50,
                max=99.9,
                default=95)
            private$..pathDiagram <- jmvcore::OptionBool$new(
                "pathDiagram",
                pathDiagram,
                default=FALSE)
            private$..pathDiagramLabel <- jmvcore::OptionBool$new(
                "pathDiagramLabel",
                pathDiagramLabel,
                default=TRUE)
            private$..pathDiagramEst <- jmvcore::OptionBool$new(
                "pathDiagramEst",
                pathDiagramEst,
                default=TRUE)
            private$..pathDiagramSig <- jmvcore::OptionBool$new(
                "pathDiagramSig",
                pathDiagramSig,
                default=TRUE)
            private$..pathDiagramMainEffect <- jmvcore::OptionBool$new(
                "pathDiagramMainEffect",
                pathDiagramMainEffect,
                default=FALSE)
            private$..simpleSlopeEst <- jmvcore::OptionBool$new(
                "simpleSlopeEst",
                simpleSlopeEst,
                default=FALSE)
            private$..simpleSlopePlot <- jmvcore::OptionBool$new(
                "simpleSlopePlot",
                simpleSlopePlot,
                default=FALSE)

            self$.addOption(private$..dep)
            self$.addOption(private$..mod)
            self$.addOption(private$..pred)
            self$.addOption(private$..estMethod)
            self$.addOption(private$..bootstrap)
            self$.addOption(private$..label)
            self$.addOption(private$..test)
            self$.addOption(private$..ci)
            self$.addOption(private$..ciWidth)
            self$.addOption(private$..pathDiagram)
            self$.addOption(private$..pathDiagramLabel)
            self$.addOption(private$..pathDiagramEst)
            self$.addOption(private$..pathDiagramSig)
            self$.addOption(private$..pathDiagramMainEffect)
            self$.addOption(private$..simpleSlopeEst)
            self$.addOption(private$..simpleSlopePlot)
        }),
    active = list(
        dep = function() private$..dep$value,
        mod = function() private$..mod$value,
        pred = function() private$..pred$value,
        estMethod = function() private$..estMethod$value,
        bootstrap = function() private$..bootstrap$value,
        label = function() private$..label$value,
        test = function() private$..test$value,
        ci = function() private$..ci$value,
        ciWidth = function() private$..ciWidth$value,
        pathDiagram = function() private$..pathDiagram$value,
        pathDiagramLabel = function() private$..pathDiagramLabel$value,
        pathDiagramEst = function() private$..pathDiagramEst$value,
        pathDiagramSig = function() private$..pathDiagramSig$value,
        pathDiagramMainEffect = function() private$..pathDiagramMainEffect$value,
        simpleSlopeEst = function() private$..simpleSlopeEst$value,
        simpleSlopePlot = function() private$..simpleSlopePlot$value),
    private = list(
        ..dep = NA,
        ..mod = NA,
        ..pred = NA,
        ..estMethod = NA,
        ..bootstrap = NA,
        ..label = NA,
        ..test = NA,
        ..ci = NA,
        ..ciWidth = NA,
        ..pathDiagram = NA,
        ..pathDiagramLabel = NA,
        ..pathDiagramEst = NA,
        ..pathDiagramSig = NA,
        ..pathDiagramMainEffect = NA,
        ..simpleSlopeEst = NA,
        ..simpleSlopePlot = NA)
)

modResults <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
    "modResults",
    inherit = jmvcore::Group,
    active = list(
        mod = function() private$.items[["mod"]],
        pathDiagram = function() private$.items[["pathDiagram"]],
        simpleSlope = function() private$.items[["simpleSlope"]],
        modelSyntax = function() private$..modelSyntax),
    private = list(
        ..modelSyntax = NA),
    public=list(
        initialize=function(options) {
            super$initialize(
                options=options,
                name="",
                title="Moderation")
            self$add(jmvcore::Table$new(
                options=options,
                name="mod",
                title="Moderation Estimates",
                clearWith=list(
                    "dep",
                    "pred",
                    "mod",
                    "estMethod",
                    "bootstrap",
                    "ciWidth"),
                columns=list(
                    list(
                        `name`="term", 
                        `title`="", 
                        `type`="text"),
                    list(
                        `name`="label", 
                        `title`="Label", 
                        `type`="text", 
                        `format`="narrow", 
                        `visible`="(label)"),
                    list(
                        `name`="est", 
                        `title`="Estimate", 
                        `type`="number"),
                    list(
                        `name`="se", 
                        `title`="SE", 
                        `type`="number"),
                    list(
                        `name`="lower", 
                        `title`="Lower", 
                        `type`="number", 
                        `visible`="(ci)"),
                    list(
                        `name`="upper", 
                        `title`="Upper", 
                        `type`="number", 
                        `visible`="(ci)"),
                    list(
                        `name`="z", 
                        `title`="Z", 
                        `type`="number", 
                        `visible`="(test)"),
                    list(
                        `name`="p", 
                        `title`="p", 
                        `type`="number", 
                        `format`="zto,pvalue", 
                        `visible`="(test)"))))
            self$add(jmvcore::Image$new(
                options=options,
                name="pathDiagram",
                title="Path Diagram",
                width=500,
                height=300,
                renderFun=".pathDiagram",
                visible="(pathDiagram)",
                clearWith=list(
                    "dep",
                    "pred",
                    "pathDiagramLabel",
                    "pathDiagramMainEffect",
                    "pathDiagramEst",
                    "pathDiagramSig",
                    "mod",
                    "estMethod",
                    "bootstrap")))
            self$add(R6::R6Class(
                inherit = jmvcore::Group,
                active = list(
                    estimates = function() private$.items[["estimates"]],
                    plot = function() private$.items[["plot"]]),
                private = list(),
                public=list(
                    initialize=function(options) {
                        super$initialize(
                            options=options,
                            name="simpleSlope",
                            title="Simple Slope Analysis")
                        self$add(jmvcore::Table$new(
                            options=options,
                            name="estimates",
                            title="Simple Slope Estimates",
                            visible="(simpleSlopeEst)",
                            clearWith=list(
                                "dep",
                                "pred",
                                "mod",
                                "estMethod",
                                "bootstrap",
                                "ciWidth"),
                            columns=list(
                                list(
                                    `name`="term", 
                                    `title`="", 
                                    `type`="text"),
                                list(
                                    `name`="est", 
                                    `title`="Estimate", 
                                    `type`="number"),
                                list(
                                    `name`="se", 
                                    `title`="SE", 
                                    `type`="number"),
                                list(
                                    `name`="lower", 
                                    `title`="Lower", 
                                    `type`="number", 
                                    `visible`="(ci)"),
                                list(
                                    `name`="upper", 
                                    `title`="Upper", 
                                    `type`="number", 
                                    `visible`="(ci)"),
                                list(
                                    `name`="z", 
                                    `title`="Z", 
                                    `type`="number", 
                                    `visible`="(test)"),
                                list(
                                    `name`="p", 
                                    `title`="p", 
                                    `type`="number", 
                                    `format`="zto,pvalue", 
                                    `visible`="(test)"))))
                        self$add(jmvcore::Image$new(
                            options=options,
                            name="plot",
                            title="Simple Slope Plot",
                            width=550,
                            height=400,
                            renderFun=".simpleSlopePlot",
                            visible="(simpleSlopePlot)",
                            clearWith=list(
                                "dep",
                                "pred",
                                "mod",
                                "estMethod",
                                "bootstrap",
                                "ciWidth")))}))$new(options=options))
            private$..modelSyntax <- NULL},
        .setModelSyntax=function(x) private$..modelSyntax <- x))

modBase <- if (requireNamespace("jmvcore", quietly=TRUE)) R6::R6Class(
    "modBase",
    inherit = jmvcore::Analysis,
    public = list(
        initialize = function(options, data=NULL, datasetId="", analysisId="", revision=0) {
            super$initialize(
                package = "medmod",
                name = "mod",
                version = c(1,0,0),
                options = options,
                results = modResults$new(options=options),
                data = data,
                datasetId = datasetId,
                analysisId = analysisId,
                revision = revision,
                pause = NULL,
                completeWhenFilled = FALSE,
                requiresMissings = FALSE,
                weightsSupport = 'auto')
        }))

#' Moderation
#'
#' Simple moderation analysis. Estimates a model in which the effect of a 
#' predictor on the dependent variable depends on the value of a moderator, 
#' testing the main effects of predictor and moderator and their interaction. 
#' All variables are mean-centered before the model is fitted with the lavaan 
#' package (Rosseel, 2012); standard errors are computed with the delta method 
#' or by bootstrapping. Optionally provides a simple slope analysis with a 
#' corresponding plot, and an annotated path diagram of the model.
#'
#' @examples
#' set.seed(1234)
#' X <- rnorm(100)
#' M <- rnorm(100)
#' X_M <- X*M
#' Y <- 0.7*X + 0.1*M + 4.2*X_M + rnorm(100)
#' dat <- data.frame(X=X, M=M, Y=Y)
#'
#' mod(dat, dep = "Y", pred = "X", mod = "M")
#'
#' #
#' #  Moderation Estimates
#' #  --------------------------------------------------
#' #             Estimate    SE        Z        p
#' #  --------------------------------------------------
#' #    X           0.951    0.0965     9.86    < .001
#' #    M          -0.471    0.0923    -5.10    < .001
#' #    X:M         4.185    0.1009    41.50    < .001
#' #  --------------------------------------------------
#' #
#' #
#'
#' @param data the data as a data frame
#' @param dep a string naming the dependent variable
#' @param mod a string naming the moderator variable
#' @param pred a string naming the predictor variable
#' @param estMethod \code{'standard'} (default), or \code{'bootstrap'}, the
#'   estimation method to use
#' @param bootstrap a number between 1 and 100000 (default: 1000) specifying
#'   the number of  samples that need to been drawn in the bootstrap method
#' @param label \code{TRUE} or \code{FALSE} (default), provide the coefficient
#'   labels (b1, b2, b3) used in the model and the path diagram
#' @param test \code{TRUE} (default) or \code{FALSE}, provide 'Z' and 'p'
#'   values for the mediation estimates
#' @param ci \code{TRUE} or \code{FALSE} (default), provide a confidence
#'   interval for the mediation estimates
#' @param ciWidth a number between 50 and 99.9 (default: 95) specifying the
#'   confidence interval width that is used as \code{'ci'}
#' @param pathDiagram \code{TRUE} or \code{FALSE} (default), provide a
#'   conceptual path diagram of the moderation model.
#' @param pathDiagramLabel \code{TRUE} (default) or \code{FALSE}, annotate the
#'   path diagram arrows with the path labels.
#' @param pathDiagramEst \code{TRUE} (default) or \code{FALSE}, annotate the
#'   path diagram arrows with the estimated coefficients.
#' @param pathDiagramSig \code{TRUE} (default) or \code{FALSE}, annotate the
#'   path diagram arrows with significance stars.
#' @param pathDiagramMainEffect \code{TRUE} or \code{FALSE} (default), draw
#'   the moderator's main effect on the dependent variable (b2) in the path
#'   diagram.
#' @param simpleSlopeEst \code{TRUE} or \code{FALSE} (default), provide the
#'   estimates of the simple slopes.
#' @param simpleSlopePlot \code{TRUE} or \code{FALSE} (default), provide a
#'   plot of the simple slopes.
#' @return A results object containing:
#' \tabular{llllll}{
#'   \code{results$mod} \tab \tab \tab \tab \tab a table containing moderation estimates \cr
#'   \code{results$pathDiagram} \tab \tab \tab \tab \tab an image \cr
#'   \code{results$simpleSlope$estimates} \tab \tab \tab \tab \tab a table containing the simple slope estimates \cr
#'   \code{results$simpleSlope$plot} \tab \tab \tab \tab \tab an image \cr
#'   \code{results$modelSyntax} \tab \tab \tab \tab \tab the lavaan syntax used to fit the moderation model \cr
#' }
#'
#' Tables can be converted to data frames with \code{asDF} or \code{\link{as.data.frame}}. For example:
#'
#' \code{results$mod$asDF}
#'
#' \code{as.data.frame(results$mod)}
#'
#' @export
mod <- function(
    data,
    dep,
    mod,
    pred,
    estMethod = "standard",
    bootstrap = 1000,
    label = FALSE,
    test = TRUE,
    ci = FALSE,
    ciWidth = 95,
    pathDiagram = FALSE,
    pathDiagramLabel = TRUE,
    pathDiagramEst = TRUE,
    pathDiagramSig = TRUE,
    pathDiagramMainEffect = FALSE,
    simpleSlopeEst = FALSE,
    simpleSlopePlot = FALSE) {

    if ( ! requireNamespace("jmvcore", quietly=TRUE))
        stop("mod requires jmvcore to be installed (restart may be required)")

    if ( ! missing(dep)) dep <- jmvcore::resolveQuo(jmvcore::enquo(dep))
    if ( ! missing(mod)) mod <- jmvcore::resolveQuo(jmvcore::enquo(mod))
    if ( ! missing(pred)) pred <- jmvcore::resolveQuo(jmvcore::enquo(pred))
    if (missing(data))
        data <- jmvcore::marshalData(
            parent.frame(),
            `if`( ! missing(dep), dep, NULL),
            `if`( ! missing(mod), mod, NULL),
            `if`( ! missing(pred), pred, NULL))


    options <- modOptions$new(
        dep = dep,
        mod = mod,
        pred = pred,
        estMethod = estMethod,
        bootstrap = bootstrap,
        label = label,
        test = test,
        ci = ci,
        ciWidth = ciWidth,
        pathDiagram = pathDiagram,
        pathDiagramLabel = pathDiagramLabel,
        pathDiagramEst = pathDiagramEst,
        pathDiagramSig = pathDiagramSig,
        pathDiagramMainEffect = pathDiagramMainEffect,
        simpleSlopeEst = simpleSlopeEst,
        simpleSlopePlot = simpleSlopePlot)

    analysis <- modClass$new(
        options = options,
        data = data)

    analysis$run()

    analysis$results
}

Try the medmod package in your browser

Any scripts or data that you put into this service are public.

medmod documentation built on July 16, 2026, 9:07 a.m.