semPower.powerMediation {semPower}R Documentation

semPower.powerMediation

Description

Convenience function for performing power analysis concerning indirect effect(s) in a mediation model. This requires the lavaan package.

Usage

semPower.powerMediation(
  type,
  comparison = "restricted",
  bYX = NULL,
  bMX = NULL,
  bYM = NULL,
  Beta = NULL,
  indirect = NULL,
  nullEffect = "ind = 0",
  nullWhichGroups = NULL,
  standardized = TRUE,
  ...
)

Arguments

type

type of power analysis, one of 'a-priori', 'post-hoc', 'compromise'.

comparison

comparison model, one of 'saturated' or 'restricted' (the default). This determines the df for power analyses. 'saturated' provides power to reject the model when compared to the saturated model, so the df equal the one of the hypothesized model. 'restricted' provides power to reject the hypothesized model when compared to an otherwise identical model that just omits the restrictions defined in nullEffect, so the df equal the number of restrictions.

bYX

the slope (direct effect) for X -> Y. A list for multiple group models. Can be NULL if Beta is set.

bMX

the slope for X -> M. A list for multiple group models. Can be NULL if Beta is set.

bYM

the slope for M -> Y. A list for multiple group models. Can be NULL if Beta is set.

Beta

can be used instead of bYX, bMX, and bYM: matrix of regression weights connecting the latent factors (all-Y notation). Exogenous variables must be in the first row(s), so the upper triangular of Beta must be zero. A list for multiple group models.

indirect

NULL unless Beta is set. Otherwise a list of vectors of size 2 indicating the elements of Beta that define the indirect effect of interest, e.g. list(c(2, 1), c(3, 2)). See details.

nullEffect

defines the hypothesis of interest, must be one of 'ind = 0' (the default) to test whether the indirect effect is zero or 'indA = indB' to test for the equality of indirect effects across groups. See details.

nullWhichGroups

for nullEffect = 'indA = indB', vector indicating the groups for which equality constrains should be applied, e.g. c(1, 3) to constrain the relevant parameters of the first and the third group. If NULL, all groups are constrained to equality.

standardized

whether all parameters should be standardized (TRUE, the default). If FALSE, all regression relations are unstandardized.

...

mandatory further parameters related to the specific type of power analysis requested, see semPower.aPriori(), semPower.postHoc(), and semPower.compromise(), and parameters specifying the factor model. In case of a simple mediation, the order of factors is X, M, Y. See details.

Details

This function performs a power analysis to reject various hypotheses arising in the context of mediation:

The indirect effect of interest can be specified in two ways:

Notes on implementation:

Tofighi, D., & Kelley, K. (2020). Improved inference in mediation analysis: Introducing the model-based constrained optimization procedure. Psychological Methods, 25(4), 496–515. https://doi.org/10.1037/met0000259

Beyond the arguments explicitly contained in the function call, additional arguments are required specifying the factor model and the requested type of power analysis.

Additional arguments related to the definition of the factor model:

So either Lambda, or loadings, or nIndicator and loadM need to be defined. If the model contains observed variables only, use Lambda = diag(x) where x is the number of variables.

Note that in case of a simple mediation model involving three variables, the order of the factors is X, M, Y, i. e., the first factor is treated as X, the second as M, and the thrird as Y. In case of a more complex mediation defined via the Beta matrix, the order of factors matches the order of Beta.

Additional arguments related to the requested type of power analysis:

If a simulated power analysis (simulatedPower = TRUE) is requested, optional arguments can be provided as a list to simOptions:

type = 'IG' implements the independent generator approach (IG, Foldnes & Olsson, 2016) approach specifying third and fourth moments of the marginals, and thus requires that skewness (skewness) and excess kurtosis (kurtosis) for each variable are provided as vectors. This requires the covsim package.

type = 'mnonr' implements the approach suggested by Qu, Liu, & Zhang (2020) and requires provision of Mardia's multivariate skewness (skewness) and kurtosis (kurtosis), where skewness must be non-negative and kurtosis must be at least 1.641 skewness + p (p + 0.774), where p is the number of variables. This requires the mnonr package.

type = 'RK' implements the approach suggested by Ruscio & Kaczetow (2008) and requires provision of the population distributions of each variable (distributions). distributions must be a list (if all variables shall be based on the same population distribution) or a list of lists. Each component must specify the population distribution (e.g. rchisq) and additional arguments (list(df = 2)).

type = 'VM' implements the third-order polynomial method (Vale & Maurelli, 1983) specifying third and fourth moments of the marginals, and thus requires that skewness (skewness) and excess kurtosis (kurtosis) for each variable are provided as vectors. This requires the semTools package.

Value

a list. Use the summary method to obtain formatted results. Beyond the results of the power analysis and a number of effect size measures, the list contains the following components:

Sigma

the population covariance matrix. A list for multiple group models.

mu

the population mean vector or NULL when no meanstructure is involved. A list for multiple group models.

SigmaHat

the H0 model implied covariance matrix. A list for multiple group models.

muHat

the H0 model implied mean vector or NULL when no meanstructure is involved. A list for multiple group models.

modelH0

lavaan H0 model string.

modelH1

lavaan H1 model string or NULL when the comparison refers to the saturated model.

simRes

detailed simulation results when a simulated power analysis (simulatedPower = TRUE) was performed.

See Also

semPower.genSigma() semPower.aPriori() semPower.postHoc() semPower.compromise()

Examples

## Not run: 
# simple case of X -> M -> Y mediation in the form of
# X -- .30 --> M -- .40 --> Y
# X --------- .25 --------> Y
# determine the required N to detect the indirect effect of >= .12 (= .3 * .4) 
# with a power of 95% on alpha = 5%, where   
# X is measured by 3 indicators loading by .5 each, 
# M is measured by 5 indicators loading by .6 each, 
# Y is measured by 4 indicators loading by .7 each.
powerMed <- semPower.powerMediation(type = 'a-priori',
                                    bYX = .25, bMX = .3, bYM = .4,
                                    nIndicator = c(3, 5, 4),
                                    loadM = c(.5, .6, .7),
                                    alpha = .05, beta = .05)
# show summary
summary(powerMed)
# optionally use lavaan to verify the model was set-up as intended
lavaan::sem(powerMed$modelH1, sample.cov = powerMed$Sigma,
sample.nobs = powerMed$requiredN, sample.cov.rescale = FALSE)
lavaan::sem(powerMed$modelH0, sample.cov = powerMed$Sigma,
sample.nobs = powerMed$requiredN, sample.cov.rescale = FALSE)

# same as above, but determine power with N = 500 on alpha = .05
powerMed <- semPower.powerMediation(type = 'post-hoc',
                                    bYX = .25, bMX = .3, bYM = .4,
                                    nIndicator = c(3, 5, 4),
                                    loadM = c(.5, .6, .7),
                                    alpha = .05, N = 500)

# same as above, but determine the critical chi-square with N = 500 so that alpha = beta
powerMed <- semPower.powerMediation(type = 'compromise',
                                    bYX = .25, bMX = .3, bYM = .4,
                                    nIndicator = c(3, 5, 4),
                                    loadM = c(.5, .6, .7),
                                    abratio = 1, N = 500)

# same as above, but compare to the saturated model
# (rather than to the less restricted model)
powerMed <- semPower.powerMediation(type = 'a-priori',
                                    comparison = 'saturated',
                                    bYX = .25, bMX = .3, bYM = .4,
                                    nIndicator = c(3, 5, 4),
                                    loadM = c(.5, .6, .7),
                                    alpha = .05, beta = .05)

# same as above, but assuming observed variables only (Lambda = diag(3))
powerMed <- semPower.powerMediation(type = 'a-priori',
                                    bYX = .25, bMX = .3, bYM = .4,
                                    Lambda = diag(3),
                                    alpha = .05, beta = .05)


# same mediation model as above, but specifying Beta and indirect
Beta <- matrix(c(
  #   X    M    Y
  c(.00, .00, .00),    # X
  c(.30, .00, .00),    # M
  c(.25, .40, .00)     # Y
), byrow = TRUE, ncol = 3)
powerMed <- semPower.powerMediation(type = 'a-priori',
                                    Beta = Beta, 
                                    indirect = list(c(2, 1), c(3, 2)),
                                    nIndicator = c(3, 5, 4),
                                    loadM = c(.5, .6, .7),
                                    alpha = .05, beta = .05)

# Beta for a more complex mediation hypothesis
# of the form X -- .2 --> M1 -- .3 --> M2 -- .40 -> Y 
# (and all other effects being zero)
# using a reduced loading matrix to define that
# X is measured by 3 indicators loading by .4, .5, .8 
# M1 is measured by 4 indicators loading by .7, .6, .5, .8
# M2 is measured by 5 indicators loading by .5, .6, .3, .4, .6 
# Y is measured by 4 indicators loading by .6, .7, .8
Beta <- matrix(c(
  c(.00, .00, .00, .00),       # X
  c(.20, .00, .00, .00),       # M1
  c(.00, .30, .00, .00),       # M2
  c(.00, .00, .40, .00)        # Y
), byrow = TRUE, ncol = 4)
loadings <- list(
  c(0.4, 0.5, 0.8),           # X
  c(0.7, 0.6, 0.5, 0.8),      # M1
  c(0.5, 0.6, 0.3, 0.4, 0.6), # M2
  c(0.6, 0.7, 0.8)            # Y
)
powerMed <- semPower.powerMediation(type = 'a-priori',
                                    Beta = B, 
                                    indirect = list(c(2, 1), 
                                                    c(3, 2), 
                                                    c(4, 3)),
                                    loadings = loadings,
                                    alpha = .05, beta = .05)

# Determine required N to detect that the indirect effect 
# in group 1 (of .2 * .3 = .09) differs from the indirect effect 
# in group 2 (of .3 * .5 = .15).
# The direct effect of X on Y is .25 in both groups.  
# The model is based on observed variables only (Lambda = diag(3))
# Both groups are sized equally (N = list(1, 1)).
powerMed <- semPower.powerMediation(type = 'a-priori',
                                    nullEffect = 'indA = indB',
                                    bYX = list(.25, .25), 
                                    bMX = list(.2, .3), 
                                    bYM = list(.3, .5),
                                    Lambda = diag(3),
                                    alpha = .05, beta = .05, N = list(1, 1))

# same as above, but specifying Beta 
Beta1 <- matrix(c(
  c(.00, .00, .00),    # X
  c(.20, .00, .00),    # M
  c(.25, .30, .00)     # Y
), byrow = TRUE, ncol = 3)
Beta2 <- matrix(c(
  c(.00, .00, .00),    # X
  c(.30, .00, .00),    # M
  c(.25, .50, .00)     # Y
), byrow = TRUE, ncol = 3)
powerMed <- semPower.powerMediation(type = 'a-priori',
                                    nullEffect = 'indA = indB',
                                    Beta = list(Beta1, Beta2), 
                                    indirect = list(c(2, 1), c(3, 2)),
                                    Lambda = diag(3),
                                    alpha = .05, beta = .05, N = list(1, 1))

# request a simulated post-hoc power analysis with 500 replications.
set.seed(300121)
powerMed <- semPower.powerMediation(type = 'post-hoc',
                                    bYX = .25, bMX = .3, bYM = .4,
                                    nIndicator = c(3, 5, 4),
                                    loadM = c(.5, .6, .7),
                                    alpha = .05, N = 500,
                                    simulatedPower = TRUE, 
                                    simOptions = list(nReplications = 500))

## End(Not run)

[Package semPower version 2.1.0 Index]