├── .Rbuildignore ├── .gitattributes ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── MeMoBootR.Rproj ├── NAMESPACE ├── R testing ├── datascreen.lme.R └── mediation1.lme.R ├── R ├── createformula.R ├── datascreen.R ├── draw.med.R ├── indirectmed.R ├── indirectmed2.R ├── indirectmed2_moda.R ├── mediation1.R ├── mediation2.R ├── mediation2_data.R ├── mediation2_moda.R ├── moderation1.R └── moderation2.R ├── README.md ├── create git.R ├── data └── mediation2_data.Rdata ├── examples ├── MeMo Handout.docx ├── example_mediation1 cat.R ├── example_mediation1.R ├── example_mediation2.R ├── example_mediation2_moda.R ├── example_moderation1 cat.R ├── example_moderation1.R ├── example_moderation2.R ├── mediation1 cat.docx ├── mediation1.csv ├── mediation1.docx ├── mediation1.sav ├── mediation2.csv ├── mediation2.docx ├── mediation2.sav ├── moderation1 cat.docx ├── moderation1.csv ├── moderation1.docx ├── moderation1.sav └── moderation2.docx ├── man ├── createformula.Rd ├── datascreen.Rd ├── draw.med.Rd ├── indirectmed.Rd ├── indirectmed2.Rd ├── indirectmed2_moda.Rd ├── mediation1.Rd ├── mediation2.Rd ├── mediation2_data.Rd ├── mediation2_moda.Rd ├── moderation1.Rd └── moderation2.Rd └── model numbers ├── model 1 CVs.jpg ├── model 1 cat.png ├── model 1.jpg ├── model 2 CVs.jpg ├── model 2.jpg ├── model 4 CVs.jpg ├── model 4 cat.jpg ├── model 4.jpg ├── model 6 CVs.jpg ├── model 6.jpg └── model numbers.docx /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # History files 2 | .Rhistory 3 | .Rapp.history 4 | 5 | # Session Data files 6 | .RData 7 | 8 | # Example code in package build process 9 | *-Ex.R 10 | 11 | # Output files from R CMD build 12 | /*.tar.gz 13 | 14 | # Output files from R CMD check 15 | /*.Rcheck/ 16 | 17 | # RStudio files 18 | .Rproj.user/ 19 | 20 | # produced vignettes 21 | vignettes/*.html 22 | vignettes/*.pdf 23 | 24 | # OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 25 | .httr-oauth 26 | 27 | # knitr and R markdown default cache directories 28 | /*_cache/ 29 | /cache/ 30 | 31 | # Temporary files created by R markdown 32 | *.utf8.md 33 | *.knit.md 34 | 35 | # Shiny token, see https://shiny.rstudio.com/articles/shinyapps.html 36 | rsconnect/ 37 | .Rproj.user 38 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: MeMoBootR 2 | Title: Mediation-Moderation with Bootstrapping in R 3 | Version: 0.0.0.7001 4 | Authors@R: person("Erin", "Buchanan", email = "buchananlab@gmail.com", role = c("aut", "cre")) 5 | Description: This package compiles mediation and mmoderation analyses wherein a user can run either analysis with data screening and see output similar to PROCESS (Hayes, 2018) from SPSS. 6 | Depends: R (>= 3.5.0), boot, diagram, ggplot2 7 | License: LGPL-3 8 | Encoding: UTF-8 9 | LazyData: true 10 | RoxygenNote: 7.0.0 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Dr. Erin M. Buchanan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /MeMoBootR.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(createformula) 4 | export(datascreen) 5 | export(draw.med) 6 | export(indirectmed) 7 | export(indirectmed2) 8 | export(indirectmed2_moda) 9 | export(mediation1) 10 | export(mediation2) 11 | export(mediation2_moda) 12 | export(moderation1) 13 | export(moderation2) 14 | -------------------------------------------------------------------------------- /R testing/datascreen.lme.R: -------------------------------------------------------------------------------- 1 | #' Data Screening for Regression 2 | #' 3 | #' This function using the data screening procedures outlined 4 | #' by Tabachnick and Fidell (2012) to analyze the data for outliers 5 | #' using Mahalanobis distance, Cook's, and Leverage values. 6 | #' Further, the output includes correlations for additivity/multicollinearity, 7 | #' and plots for linearity, normality, and homogeneity/homoscedasticity. 8 | #' You can learn more about the data screening procedure implemented here at 9 | #' the Statistics of DOOM YouTube channel. 10 | #' 11 | #' @param eq The full equation with all x, m, and cvs created from the 12 | #' \code{createformula()} function. 13 | #' @param df The dataframe where the columns from the formula can 14 | #' be found. Note that only the columns used in the analysis will be screened. 15 | #' @param with_out A logical value where you want to keep the outliers in 16 | #' the data screening \code{TRUE} or exclude them from the data screening \code{FALSE}. 17 | #' @param ... Other arguments that might be included for customizing your lme analysis. 18 | #' If none are defined, the method argument will be set to ML for maximum likelihood, and na.action will 19 | #' be set to na.omit. 20 | #' @keywords mediation, moderation, regression, data screening 21 | #' @export 22 | #' @examples 23 | #' datascreen(eq = "mpg ~ cyl + disp + drat + gear", 24 | #' df = mtcars, with_out = TRUE) 25 | #' @export 26 | 27 | datascreen = function(eq, df, with_out = T, ...) { 28 | 29 | output = lme(eq, 30 | data = df, 31 | method = method.lme, 32 | na.action = na.action.lme, 33 | random = random.lme) 34 | 35 | lme(answer ~ fsg + sospan, 36 | data = ospan, 37 | method = "ML", 38 | na.action = "na.omit", 39 | random = ~1|part_no) 40 | 41 | columnstopull = variable.names(output)[-1] 42 | 43 | mahalcolumns = columnstopull[columnstopull %in% colnames(df)] 44 | 45 | if (length(mahalcolumns) > 1){ #only run mahalanobis if there are continuous variables 46 | ##Mahal 47 | mahal = mahalanobis(df[ ,mahalcolumns], 48 | colMeans(df[ , mahalcolumns]), 49 | cov(df[ , mahalcolumns])) 50 | cutmahal = qchisq(1-.001, ncol(df[ , mahalcolumns])) 51 | badmahal = as.numeric(mahal > cutmahal) 52 | } 53 | 54 | ##leverage 55 | k = length(output$coefficients)-1 ##number of IVs 56 | leverage = hatvalues(output) 57 | cutleverage = (2*k+2) / nrow(df) 58 | badleverage = as.numeric(leverage > cutleverage) 59 | 60 | ##cooks 61 | cooks = cooks.distance(output) 62 | cutcooks = 4 / (nrow(df) - k - 1) 63 | badcooks = as.numeric(cooks > cutcooks) 64 | 65 | if (length(mahalcolumns) > 1) { 66 | ##totaloutliers 67 | totalout = badmahal + badleverage + badcooks 68 | ##make new data frame to return 69 | df2 = cbind(df, badmahal, badleverage, badcooks, totalout) 70 | } else { 71 | ##total outliers 72 | totalout = badleverage + badcooks 73 | ##make a new data frame to return 74 | df2 = cbind(df, badleverage, badcooks, totalout) 75 | } 76 | 77 | #run with or without outliers 78 | if (with_out == F) { finaldata = subset(df2, totalout < 2) } else { finaldata = df2 } 79 | 80 | output2 = lm(eq, data = finaldata) 81 | 82 | ##additivity 83 | get_correl = summary(output2, correlation = T) 84 | 85 | ##assumptions 86 | standardized = rstudent(output2) 87 | fitted = scale(output2$fitted.values) 88 | 89 | ##linearity 90 | qqnorm(standardized); abline(0,1) 91 | line_plot = recordPlot() 92 | 93 | ##normality 94 | hist(standardized) 95 | hist_plot = recordPlot() 96 | 97 | ##homog and s 98 | plot(fitted, standardized) 99 | abline(0,0) 100 | abline(v = 0) 101 | homogs_plot = recordPlot() 102 | 103 | return(list(fulldata = df2, 104 | correl = get_correl$correlation, 105 | linearity = line_plot, 106 | normality = hist_plot, 107 | homogen = homogs_plot)) 108 | } 109 | 110 | #' @rdname datascreen 111 | #' @export 112 | -------------------------------------------------------------------------------- /R testing/mediation1.lme.R: -------------------------------------------------------------------------------- 1 | #' Simple Multilevel Mediation Model 2 | #' 3 | #' This function runs a complete simple mediation analysis with one 4 | #' mediator, similiar to model 4 in PROCESS by A. Hayes (2013) using 5 | #' the \code{lme} function from the \code{nlme} package for a multilevel 6 | #' analysis. 7 | #' 8 | #' As part of the output, you will find data screening, 9 | #' all three models used in the traditional Baron and 10 | #' Kenny (1986) steps, total/direct/indirect effects, the z-score and p-value 11 | #' for the Aroian Sobel test, and the bootstrapped confidence interval 12 | #' for the indirect effect. 13 | #' 14 | #' @param y The dependent variable column name from your dataframe. 15 | #' @param x The independent variable column name from your dataframe. This column 16 | #' will be treated as X in mediation or moderation models, please see 17 | #' diagrams online for examples. 18 | #' @param m The mediator for your model, as this model only includes one mediator. 19 | #' @param cvs The covariates you would like to include in the model. 20 | #' Use a \code{c()} concatenated vector to use multiple covariates. 21 | #' @param df The dataframe where the columns from the formula can be found. 22 | #' Note that only the columns used in the analysis will be data screened. 23 | #' @param with_out A logical value where you want to keep the outliers in 24 | #' model \code{TRUE} or exclude them from the model \code{FALSE}. 25 | #' @param nboot A numeric value indicating the number of bootstraps you would like to complete. 26 | #' @param conf_level A numeric value indicating the confidence interval width for the boostrapped confidence interval. 27 | #' @param random.lme A character vector indicating the random effects you wish to include in the model. 28 | #' To use only random intercepts include: \code{"~1|INTERCEPT"} where INTERCEPT is a column name in the dataframe. 29 | #' To use random intercepts and random slopes include: \code{"SLOPE|INTERCEPT"} where SLOPE is the column 30 | #' name in the dataframe for the random slopes, and INTERCEPT is the column for the random intercepts. 31 | #' If you wish to use multiple slopes or intercepts use \code{c()} to concatenate them together. 32 | #' @param ... Other arguments that might be included for customizing your lme analysis. 33 | #' If none are defined, the method argument will be set to ML for maximum likelihood, and na.action will 34 | #' be set to na.omit. 35 | #' @keywords mediation, regression, data screening, bootstrapping 36 | #' @export 37 | #' @examples 38 | #' Dataset can be found on our OSF page and GitHub for this package. 39 | #' mediation1.mlm() 40 | #' 41 | #' @export 42 | 43 | mediation1.lme = function(y, x, m, cvs = NULL, df, with_out = T, 44 | nboot = 1000, conf_level = .95, random.lme, ...) { 45 | 46 | require(boot); require(nlme) 47 | 48 | #stop if Y is categorical 49 | if (is.factor(df[ , y])){stop("Y should not be a categorical variable. Log regression options are coming soon.")} 50 | 51 | #stop if M is categorical 52 | if (is.factor(df[ , m])){stop("M should not be a categorial variable.")} 53 | 54 | #figure out if X is categorical 55 | if (is.factor(df[ , x])){xcat = TRUE} else {xcat = FALSE} 56 | 57 | #first create the full formula for data screening 58 | allformulas = createformula(y, x, m, cvs, type = "mediation1") 59 | 60 | #figure out other arguments 61 | other.args = list(...) 62 | if (is.null(other.args$na.action)){other.args$na.action = "na.omit"} 63 | if (is.null(other.args$method)){other.args$method = "ML"} 64 | 65 | 66 | #then do data screening 67 | screen = datascreen.lme(allformulas$eq3, df, with_out, random.lme, ...) 68 | 69 | #take out outlines and create finaldata 70 | if (with_out == F) { finaldata = subset(screen$fulldata, totalout < 2) } else { finaldata = screen$fulldata } 71 | 72 | model1 = lm(allformulas$eq1, data = finaldata) #c path 73 | model2 = lm(allformulas$eq2, data = finaldata) #a path 74 | model3 = lm(allformulas$eq3, data = finaldata) #b c' paths 75 | 76 | if (xcat == F){ #run this with continuous X 77 | #aroian sobel 78 | a = coef(model2)[x] 79 | b = coef(model3)[m] 80 | SEa = summary(model2)$coefficients[x,2] 81 | SEb = summary(model3)$coefficients[m,2] 82 | zscore = (a*b)/(sqrt((b^2*SEa^2)+(a^2*SEb^2)+(SEa^2*SEb^2))) 83 | pvalue = pnorm(abs(zscore), lower.tail = F)*2 84 | 85 | #reporting 86 | total = coef(model1)[x] #c path 87 | direct = coef(model3)[x] #c' path 88 | indirect = a*b 89 | 90 | } else { 91 | 92 | #figure out all the labels for X 93 | levelsx = paste(x, levels(df[, x])[-1], sep = "") 94 | total = NA; indirect = NA; direct = NA; zscore = NA; pvalue = NA 95 | 96 | #loop over that to figure out sobel and reporting 97 | for (i in 1:length(levelsx)){ 98 | 99 | #aroian sobel 100 | a = coef(model2)[levelsx[i]] 101 | b = coef(model3)[m] 102 | SEa = summary(model2)$coefficients[levelsx[i],2] 103 | SEb = summary(model3)$coefficients[m,2] 104 | zscore[i] = (a*b)/(sqrt((b^2*SEa^2)+(a^2*SEb^2)+(SEa^2*SEb^2))) 105 | pvalue[i] = pnorm(abs(zscore[i]), lower.tail = F)*2 106 | 107 | #reporting 108 | total[i] = coef(model1)[levelsx[i]] #c path 109 | direct[i] = coef(model3)[levelsx[i]] #c' path 110 | indirect[i] = a*b 111 | 112 | } #close for loop 113 | } #close else x is categorical 114 | 115 | bootresults = boot(data = finaldata, 116 | statistic = indirectmed, 117 | formula2 = allformulas$eq2, 118 | formula3 = allformulas$eq3, 119 | x = x, 120 | med.var = m, 121 | R = nboot) 122 | 123 | if (xcat == F) { #run this if X is continuous 124 | bootci = boot.ci(bootresults, 125 | conf = conf_level, 126 | type = "norm") 127 | } else { 128 | bootci = list() 129 | for (i in 1:length(levelsx)){ 130 | bootci[[i]] = boot.ci(bootresults, 131 | conf = conf_level, 132 | type = "norm", 133 | index = i) 134 | names(bootci)[[i]] = levelsx[[i]] 135 | } #close for loop 136 | } #close else statement 137 | 138 | triangle = draw.med(model1, model2, model3, y, x, m, finaldata) 139 | 140 | return(list("datascreening" = screen, 141 | "model1" = model1, 142 | "model2" = model2, 143 | "model3" = model3, 144 | "total.effect" = total, 145 | "direct.effect" = direct, 146 | "indirect.effect" = indirect, 147 | "z.score" = zscore, 148 | "p.value" = pvalue, 149 | "boot.results" = bootresults, 150 | "boot.ci" = bootci, 151 | "diagram" = triangle 152 | )) 153 | } 154 | 155 | #' @rdname mediation1.mlm 156 | #' @export 157 | -------------------------------------------------------------------------------- /R/createformula.R: -------------------------------------------------------------------------------- 1 | #' Create Regression Formulas 2 | #' 3 | #' This function creates the formulas for \code{lm()} to run the 4 | #' regression models necessary for data screening and mediation 5 | #' or moderation models. 6 | #' 7 | #' The output currently includes a list of equations used for simple mediation, 8 | #' which will updated as moderation is added to the package. 9 | #' 10 | #' @param y The dependent variable column name from your dataframe. 11 | #' @param x The independent variable column name from your dataframe. This column will be treated as X in mediation or moderation models, please see diagrams online for examples. 12 | #' @param m The first mediator or moderator for your model. 13 | #' @param m2 The second mediator or moderator for your model. 14 | #' @param mod A moderator for a moderated mediation model. 15 | #' @param cvs The covariates you would like to include in the model. Use a `c()` concatenated vector to use multiple covariates. 16 | #' @keywords mediation, moderation, regression, formulas 17 | #' @export 18 | #' @examples 19 | #' createformula(y = "cyl", x = "mpg", m = "disp", 20 | #' cvs = c("drat", "gear"), type = "moderation1") 21 | #' @export 22 | 23 | createformula <- function (y, x, m, m2 = NULL, mod = NULL, cvs = NULL, type){ 24 | 25 | if (type == "mediation1") { 26 | 27 | if (!is.null(cvs)) { 28 | #y ~ x + cvs 29 | eq1 = paste(y, "~", x, "+", paste(cvs, collapse = " + "), sep = " ") 30 | #m ~ x + cvs 31 | eq2 = paste(m, "~", x, "+", paste(cvs, collapse = " + "), sep = " ") 32 | #y ~ x + m + cvs 33 | eq3 = paste(y, "~", x, "+", m, "+", paste(cvs, collapse = " + "), sep = " ") 34 | } else { 35 | #y ~ x 36 | eq1 = paste(y, "~", x, sep = " ") 37 | #m ~ x 38 | eq2 = paste(m, "~", x, sep = " ") 39 | #y ~ x 40 | eq3 = paste(y, "~", x, "+", m, sep = " ") 41 | } 42 | return(list("eq1" = eq1, 43 | "eq2" = eq2, 44 | "eq3" = eq3)) 45 | 46 | } #return simple mediation 47 | 48 | if (type == "mediation2") { 49 | 50 | if (!is.null(cvs)) { 51 | #y ~ x + cvs 52 | eq1 = paste(y, "~", x, "+", paste(cvs, collapse = " + "), sep = " ") 53 | #m1 ~ x + cvs 54 | eq2 = paste(m, "~", x, "+", paste(cvs, collapse = " + "), sep = " ") 55 | #m2 ~ x + m1 + cvs 56 | eq3 = paste(m2, "~", x, "+", m, "+", paste(cvs, collapse = " + "), sep = " ") 57 | #y ~ x + m + cvs 58 | eq4 = paste(y, "~", x, "+", m, "+", m2, "+", paste(cvs, collapse = " + "), sep = " ") 59 | } else { 60 | #y ~ x 61 | eq1 = paste(y, "~", x, sep = " ") 62 | #m1 ~ x + cvs 63 | eq2 = paste(m, "~", x, sep = " ") 64 | #m2 ~ x + m1 + cvs 65 | eq3 = paste(m2, "~", x, "+", m, sep = " ") 66 | #y ~ x + m + cvs 67 | eq4 = paste(y, "~", x, "+", m, "+", m2, sep = " ") 68 | } 69 | return(list("eq1" = eq1, 70 | "eq2" = eq2, 71 | "eq3" = eq3, 72 | "eq4" = eq4)) 73 | 74 | } #return serial mediation with two mediators 75 | 76 | if (type == "mediation2_moda") { 77 | 78 | if (!is.null(cvs)) { 79 | #y ~ x + cvs 80 | eq1 = paste(y, "~", x, "+", paste(cvs, collapse = " + "), sep = " ") 81 | #m1 ~ x + cvs 82 | eq2 = paste(m, "~", x, "*", mod, "+", paste(cvs, collapse = " + "), sep = " ") 83 | eq2.1 = paste(m, "~", x, "*", "lowMod", "+", paste(cvs, collapse = " + "), sep = " ") 84 | eq2.2 = paste(m, "~", x, "*", "highMod", "+", paste(cvs, collapse = " + "), sep = " ") 85 | #m2 ~ x + m1 + cvs 86 | eq3 = paste(m2, "~", x, "+", m, "+", paste(cvs, collapse = " + "), sep = " ") 87 | #y ~ x + m + cvs 88 | eq4 = paste(y, "~", x, "+", m, "+", m2, "+", paste(cvs, collapse = " + "), sep = " ") 89 | } else { 90 | #y ~ x 91 | eq1 = paste(y, "~", x, sep = " ") 92 | #m1 ~ x + cvs 93 | eq2 = paste(m, "~", x, "*", mod, sep = " ") 94 | eq2.1 = paste(m, "~", x, "*", "lowMod", sep = " ") 95 | eq2.2 = paste(m, "~", x, "*", "highMod", sep = " ") 96 | #m2 ~ x + m1 + cvs 97 | eq3 = paste(m2, "~", x, "+", m, sep = " ") 98 | #y ~ x + m + cvs 99 | eq4 = paste(y, "~", x, "+", m, "+", m2, sep = " ") 100 | } 101 | return(list("eq1" = eq1, 102 | "eq2" = eq2, 103 | "eq2.1" = eq2.1, 104 | "eq2.2" = eq2.2, 105 | "eq3" = eq3, 106 | "eq4" = eq4)) 107 | 108 | } #return serial mediation with two mediators 109 | 110 | if (type == "moderation1"){ 111 | 112 | if (!is.null(cvs)) { 113 | #y ~ x * m + cvs 114 | eq1 = paste(y, "~", x, "*", m, "+", paste(cvs, collapse = " + "), sep = " ") 115 | eq2 = paste(y, "~", x, "*", "lowM", "+", paste(cvs, collapse = " + "), sep = " ") 116 | eq3 = paste(y, "~", x, "*", "highM", "+", paste(cvs, collapse = " + "), sep = " ") 117 | } else { 118 | #y ~ x * m 119 | eq1 = paste(y, "~", x, "*", m, sep = " ") 120 | eq2 = paste(y, "~", x, "*", "lowM", sep = " ") 121 | eq3 = paste(y, "~", x, "*", "highM", sep = " ") 122 | } 123 | return(list("eq1" = eq1, 124 | "eq2" = eq2, 125 | "eq3" = eq3)) 126 | 127 | } #return simple moderation 128 | 129 | if (type == "moderation2"){ 130 | 131 | if (!is.null(cvs)) { 132 | #y ~ x * m + cvs overallmodel 133 | eq1 = paste(y, "~", x, "*", m, "+", x, "*", m2, "+", 134 | paste(cvs, collapse = " + "), sep = " ") 135 | #avg m1 low m2 136 | eq1.1 = paste(y, "~", x, "*", m, "+", x, "*", "lowM2", "+", 137 | paste(cvs, collapse = " + "), sep = " ") 138 | #avg m1 high m2 139 | eq1.2 = paste(y, "~", x, "*", m, "+", x, "*", "highM2", "+", 140 | paste(cvs, collapse = " + "), sep = " ") 141 | #low m1 avg m2 142 | eq2 = paste(y, "~", x, "*", "lowM1", "+", x, "*", m2, "+", 143 | paste(cvs, collapse = " + "), sep = " ") 144 | #low m1 low m2 145 | eq2.1 = paste(y, "~", x, "*", "lowM1", "+", x, "*", "lowM2", "+", 146 | paste(cvs, collapse = " + "), sep = " ") 147 | #low m1 high m2 148 | eq2.2 = paste(y, "~", x, "*", "lowM1", "+", x, "*", "highM2", "+", 149 | paste(cvs, collapse = " + "), sep = " ") 150 | #high m1 avg m2 151 | eq3 = paste(y, "~", x, "*", "highM1", "+", x, "*", m2, "+", 152 | paste(cvs, collapse = " + "), sep = " ") 153 | #high m1 low m2 154 | eq3.1 = paste(y, "~", x, "*", "highM1", "+", x, "*", "lowM2", "+", 155 | paste(cvs, collapse = " + "), sep = " ") 156 | #high m1 high m2 157 | eq3.2 = paste(y, "~", x, "*", "highM1", "+", x, "*", "highM2", "+", 158 | paste(cvs, collapse = " + "), sep = " ") 159 | } else { 160 | #y ~ x * m overallmodel 161 | eq1 = paste(y, "~", x, "*", m, "+", x, "*", m2, sep = " ") 162 | #avg m1 low m2 163 | eq1.1 = paste(y, "~", x, "*", m, "+", x, "*", "lowM2", sep = " ") 164 | #avg m1 high m2 165 | eq1.2 = paste(y, "~", x, "*", m, "+", x, "*", "highM2", sep = " ") 166 | #low m1 avg m2 167 | eq2 = paste(y, "~", x, "*", "lowM1", "+", x, "*", m2, sep = " ") 168 | #low m1 low m2 169 | eq2.1 = paste(y, "~", x, "*", "lowM1", "+", x, "*", "lowM2", sep = " ") 170 | #low m1 high m2 171 | eq2.2 = paste(y, "~", x, "*", "lowM1", "+", x, "*", "highM2", sep = " ") 172 | #high m1 avg m2 173 | eq3 = paste(y, "~", x, "*", "highM1", "+", x, "*", m2, sep = " ") 174 | #high m1 low m2 175 | eq3.1 = paste(y, "~", x, "*", "highM1", "+", x, "*", "lowM2", sep = " ") 176 | #high m1 high m2 177 | eq3.2 = paste(y, "~", x, "*", "highM1", "+", x, "*", "highM2", sep = " ") 178 | } 179 | return(list("eq1" = eq1, 180 | "eq2" = eq2, 181 | "eq3" = eq3, 182 | "eq1.1" = eq1.1, 183 | "eq1.2" = eq1.2, 184 | "eq2.1" = eq2.1, 185 | "eq2.2" = eq2.2, 186 | "eq3.1" = eq3.1, 187 | "eq3.2" = eq3.2)) 188 | 189 | } #return two two-way moderation 190 | 191 | } 192 | 193 | #' @rdname createformula 194 | #' @export 195 | -------------------------------------------------------------------------------- /R/datascreen.R: -------------------------------------------------------------------------------- 1 | #' Data Screening for Regression 2 | #' 3 | #' This function using the data screening procedures outlined 4 | #' by Tabachnick and Fidell (2012) to analyze the data for outliers 5 | #' using Mahalanobis distance, Cook's, and Leverage values. 6 | #' Further, the output includes correlations for additivity/multicollinearity, 7 | #' and plots for linearity, normality, and homogeneity/homoscedasticity. 8 | #' You can learn more about the data screening procedure implemented here at 9 | #' the Statistics of DOOM YouTube channel. 10 | #' 11 | #' @param eq The full equation with all x, m, and cvs created from the 12 | #' \code{createformula()} function. 13 | #' @param df The dataframe where the columns from the formula can 14 | #' be found. Note that only the columns used in the analysis will be screened. 15 | #' @param with_out A logical value where you want to keep the outliers in 16 | #' the data screening \code{TRUE} or exclude them from the data screening \code{FALSE}. 17 | #' @keywords mediation, moderation, regression, data screening 18 | #' @export 19 | #' @examples 20 | #' datascreen(eq = "mpg ~ cyl + disp + drat + gear", 21 | #' df = mtcars, with_out = TRUE) 22 | #' @export 23 | 24 | datascreen <- function(eq, df, with_out = T) { 25 | 26 | output = lm(eq, data = df) 27 | 28 | columnstopull = variable.names(output)[-1] 29 | 30 | mahalcolumns = columnstopull[columnstopull %in% colnames(df)] 31 | 32 | if (length(mahalcolumns) > 1){ #only run mahalanobis if there are continuous variables 33 | ##Mahal 34 | mahal = mahalanobis(df[ ,mahalcolumns], 35 | colMeans(df[ , mahalcolumns]), 36 | cov(df[ , mahalcolumns])) 37 | cutmahal = qchisq(1-.001, ncol(df[ , mahalcolumns])) 38 | badmahal = as.numeric(mahal > cutmahal) 39 | } 40 | 41 | ##leverage 42 | k = length(output$coefficients)-1 ##number of IVs 43 | leverage = hatvalues(output) 44 | cutleverage = (2*k+2) / nrow(df) 45 | badleverage = as.numeric(leverage > cutleverage) 46 | 47 | ##cooks 48 | cooks = cooks.distance(output) 49 | cutcooks = 4 / (nrow(df) - k - 1) 50 | badcooks = as.numeric(cooks > cutcooks) 51 | 52 | if (length(mahalcolumns) > 1) { 53 | ##totaloutliers 54 | totalout = badmahal + badleverage + badcooks 55 | ##make new data frame to return 56 | df2 = cbind(df, badmahal, badleverage, badcooks, totalout) 57 | } else { 58 | ##total outliers 59 | totalout = badleverage + badcooks 60 | ##make a new data frame to return 61 | df2 = cbind(df, badleverage, badcooks, totalout) 62 | } 63 | 64 | #run with or without outliers 65 | if (with_out == F) { finaldata = subset(df2, totalout < 2) } else { finaldata = df2 } 66 | 67 | output2 = lm(eq, data = finaldata) 68 | 69 | ##additivity 70 | get_correl = summary(output2, correlation = T) 71 | 72 | ##assumptions 73 | standardized = rstudent(output2) 74 | fitted = scale(output2$fitted.values) 75 | 76 | ##linearity 77 | qqnorm(standardized); abline(0,1) 78 | line_plot = recordPlot() 79 | 80 | ##normality 81 | hist(standardized) 82 | hist_plot = recordPlot() 83 | 84 | ##homog and s 85 | plot(fitted, standardized) 86 | abline(0,0) 87 | abline(v = 0) 88 | homogs_plot = recordPlot() 89 | 90 | return(list(fulldata = df2, 91 | correl = get_correl$correlation, 92 | linearity = line_plot, 93 | normality = hist_plot, 94 | homogen = homogs_plot)) 95 | } 96 | 97 | #' @rdname datascreen 98 | #' @export 99 | -------------------------------------------------------------------------------- /R/draw.med.R: -------------------------------------------------------------------------------- 1 | #' Simple Mediation Diagrams 2 | #' 3 | #' This function returns the code to create a simple mediation triangle, 4 | #' as well as the basic diagram using the \code{diagram} library. 5 | #' 6 | #' @param model1 The saved regression model of \code{y~x} model where X predicts Y. 7 | #' @param model2 The saved regression model of \code{m~x} model where X predicts M. 8 | #' @param model3 The saved regression model of \code{y~x+m} model where X and M predict Y. 9 | #' @param y The dependent variable from your mediation. 10 | #' @param x The x variable from your mediation. 11 | #' @param m The mediator from your mediation. 12 | #' @param df The dataframe containing the y, x, m columns. 13 | #' @keywords mediation, data screening, bootstrapping, diagram 14 | #' @export 15 | #' @examples 16 | #' draw.med(saved$model1, saved$model2, saved$model3) 17 | #' Note in this example saved is the name of the model saved from mediation1. 18 | #' You can include any form of model names that you have saved from \code{lm()}. 19 | #' You can also type \code{draw.med} in your console to get this code and edit 20 | #' the diagram parameters to your liking. 21 | #' @export 22 | 23 | draw.med <- function(model1, model2, model3, y, x, m, df) { 24 | 25 | require(diagram) 26 | #figure out x categorical 27 | if (is.factor(df[ , x])){ 28 | xcat = T 29 | levelsx = paste(x, levels(df[, x])[-1], sep = "") 30 | } else {xcat = F} 31 | 32 | if (xcat == F) { #run this if X is continuous 33 | a = round(coef(model2)[x],2) 34 | b = round(coef(model3)[m],2) 35 | c = round(coef(model1)[x],2) 36 | cprime = round(coef(model3)[x],2) 37 | } else { 38 | a = NA; c = NA; cprime = NA 39 | b = round(coef(model3)[m],2) 40 | 41 | for (i in 1:length(levelsx)) { 42 | 43 | a[i] = round(coef(model2)[levelsx[i]],2) 44 | c[i] = round(coef(model1)[levelsx[i]],2) 45 | cprime[i] = round(coef(model3)[levelsx[i]],2) 46 | 47 | a[i] = paste(levelsx[i], " = ", a[i], sep = "") 48 | c[i] = paste(levelsx[i], " = ", c[i], sep = "") 49 | cprime[i] = paste(levelsx[i], " = ", cprime[i], sep = "") 50 | 51 | } #close for loop 52 | } #close categorical x loop 53 | 54 | a = paste(a, collapse = " ") 55 | a = paste("`", a, "`", sep = "") 56 | c = paste(c, collapse = " ") 57 | c = paste("`", c, "`", sep = "") 58 | cprime = paste(cprime, collapse = " ") 59 | cprime = paste("`", cprime, "`", sep = "") 60 | 61 | bvalues = matrix(nrow = 3, ncol = 3, byrow = TRUE, 62 | data = c(0, a, 0, 63 | 0, 0, 0, 64 | b, paste(c, " (", cprime, ")", sep = ""), 0)) 65 | plotmat(bvalues, 66 | pos = c(1,2), 67 | name = c(m, x, y), 68 | box.type = "rect", 69 | box.size = 0.12, 70 | box.prop = 0.5, 71 | curve = 0, 72 | shadow.size = 0) 73 | triangle = recordPlot() 74 | 75 | return(triangle) 76 | } 77 | 78 | #' @rdname draw.med 79 | #' @export 80 | -------------------------------------------------------------------------------- /R/indirectmed.R: -------------------------------------------------------------------------------- 1 | #' Indirect Effect for Mediation 2 | #' 3 | #' This function runs a simple mediation model to calculate 4 | #' the indirect effect, which will be used for bootstrapping 5 | #' the confidence interval of the indirect effect. This function 6 | #' is used in conjunction with the \code{boot} function and is formatted to 7 | #' work as a bootstrapped effect. 8 | #' 9 | #' @param formula2 The formula for mediation for the a path, usually 10 | #' \code{m ~ x}. Can also include covariates and will be \code{eq2} 11 | #' if the \code{createformula()} function is used. 12 | #' @param formula3 The formula for mediation for the b path, usually 13 | #' \code{y ~ x + m}. Can also include covariates and will be 14 | #' \code{eq3} if the \code{createformula()} function is used. 15 | #' @param x The column name for x in the data frame. 16 | #' @param med.var The column name for m in the data frame. 17 | #' @param df The dataframe where the columns from the formula can be found. 18 | #' @param random This variable is used to denote the data frame will be 19 | #' randomize by row, as part of the \code{boot} library. 20 | #' @keywords mediation, regression, indirect effect 21 | #' @export 22 | #' @examples 23 | #' indirectmed("disp ~ mpg", "cyl ~ mpg + disp", mtcars) 24 | #' @export 25 | 26 | indirectmed = function(formula2, formula3, x, med.var, df, random) { 27 | d = df[random, ] #randomize by row 28 | 29 | #figure out x categorical 30 | if (is.factor(df[ , x])){ 31 | xcat = T 32 | levelsx = paste(x, levels(df[, x])[-1], sep = "") 33 | } else { xcat = F } 34 | 35 | #run the models 36 | model2 = lm(formula2, data = d) 37 | model3 = lm(formula3, data = d) 38 | 39 | if (xcat == F) { #run this if X is continuous 40 | a = coef(model2)[x] 41 | b = coef(model3)[med.var] 42 | indirect = a*b 43 | } else { 44 | indirect = NA 45 | for (i in 1:length(levelsx)) { 46 | a = coef(model2)[levelsx[i]] 47 | b = coef(model3)[med.var] 48 | indirect[i] = a*b 49 | } #close for loop around x 50 | } #close else statement 51 | 52 | return(indirect = indirect) 53 | } 54 | 55 | #' @rdname indirectmed 56 | #' @export 57 | -------------------------------------------------------------------------------- /R/indirectmed2.R: -------------------------------------------------------------------------------- 1 | #' Indirect Effect for Serial Mediation 2 | #' 3 | #' This function runs a serial mediation model with two mediators to calculate 4 | #' the indirect effect, which will be used for bootstrapping 5 | #' the confidence interval of the indirect effect. This function 6 | #' is used in conjunction with the \code{boot} function and is formatted to 7 | #' work as a bootstrapped effect. 8 | #' 9 | #' @param formula2 The formula for mediation for the a1 path, usually 10 | #' \code{m1 ~ x}. Can also include covariates and will be \code{eq2} 11 | #' if the \code{createformula()} function is used. 12 | #' @param formula3 The formula for mediation for the a2 and d21 paths, usually 13 | #' \code{m2 ~ x + m1}. Can also include covariates and will be 14 | #' \code{eq3} if the \code{createformula()} function is used. 15 | #' @param formula4 The formula for mediation for the b1 and b2 paths, usually 16 | #' \code{y ~ x + m1 + m2}. Can also include covariates and will be \code{eq4} if the 17 | #' \code{createformula()} function is used. 18 | #' @param x The column name for x in the data frame. 19 | #' @param m1 The column name for mediator 1 in the data frame. 20 | #' @param m2 The column name for mediator 2 in the data frame. 21 | #' @param data The dataframe where the columns from the formula can be found. 22 | #' @param random This variable is used to denote the data frame will be 23 | #' randomize by row, as part of the \code{boot} library. 24 | #' @keywords mediation, regression, indirect effect 25 | #' @export 26 | #' @examples 27 | #' indirectmed2("Q31 ~ Q151", "Q41 ~ Q151 + Q31", 28 | #' "Q11 ~ Q151 + Q31 + Q41", mtcars) 29 | #' @export 30 | 31 | indirectmed2 = function(formula2, formula3, 32 | formula4, x, m1, m2, df, random) { 33 | d = df[random, ] #randomize by row 34 | 35 | #figure out x categorical 36 | if (is.factor(df[ , x])){ 37 | xcat = T 38 | levelsx = paste(x, levels(df[, x])[-1], sep = "") 39 | } else { xcat = F } 40 | 41 | #run the models 42 | model2 = lm(formula2, data = d) 43 | model3 = lm(formula3, data = d) 44 | model4 = lm(formula4, data = d) 45 | 46 | if (xcat == F) { #run this if X is continuous 47 | 48 | #relevant coefficients 49 | a1 = coef(model2)[x] 50 | b1 = coef(model4)[m1] 51 | a2 = coef(model3)[x] 52 | b2 = coef(model4)[m2] 53 | d21 = coef(model3)[m1] 54 | 55 | indirect1 = a1*b1 56 | indirect2 = a2*b2 57 | indirect3 = a1*d21*b2 58 | 59 | } else { 60 | indirect = NA;indirect2 = NA; indirect3 = NA 61 | for (i in 1:length(levelsx)) { 62 | #relevant coefficients 63 | a1 = coef(model2)[levelsx[i]] 64 | b1 = coef(model4)[m1] 65 | a2 = coef(model3)[levelsx[i]] 66 | b2 = coef(model4)[m2] 67 | d21 = coef(model3)[m1] 68 | 69 | indirect1[i] = a1*b1 70 | indirect2[i] = a2*b2 71 | indirect3[i] = a1*d21*b2 72 | 73 | } #close for loop around x 74 | } #close else statement 75 | 76 | return(c(indirect1 = indirect1, 77 | indirect2 = indirect2, 78 | indirect3 = indirect3)) 79 | } 80 | 81 | #' @rdname indirectmed2 82 | #' @export 83 | -------------------------------------------------------------------------------- /R/indirectmed2_moda.R: -------------------------------------------------------------------------------- 1 | #' Indirect Effect for Serial Mediation and Moderator on Path A 2 | #' 3 | #' This function runs a serial mediation model with two mediators to calculate 4 | #' the indirect effect, which will be used for bootstrapping 5 | #' the confidence interval of the indirect effect. This function 6 | #' is used in conjunction with the \code{boot} function and is formatted to 7 | #' work as a bootstrapped effect. This mediation model includes a 8 | #' moderator on path A1. 9 | #' 10 | #' @param formula2 The formula for mediation for the a1 path, usually 11 | #' \code{m1 ~ x}. Can also include covariates and will be \code{eq2} 12 | #' if the \code{createformula()} function is used. This effect will 13 | #' also have a moderator for this model. 14 | #' @param formula3 The formula for mediation for the a2 and d21 paths, usually 15 | #' \code{m2 ~ x + m1}. Can also include covariates and will be 16 | #' \code{eq3} if the \code{createformula()} function is used. 17 | #' @param formula4 The formula for mediation for the b1 and b2 paths, usually 18 | #' \code{y ~ x + m1 + m2}. Can also include covariates and will be \code{eq4} if the 19 | #' \code{createformula()} function is used. 20 | #' @param x The column name for x in the data frame. 21 | #' @param m1 The column name for mediator 1 in the data frame. 22 | #' @param m2 The column name for mediator 2 in the data frame. 23 | #' @param mod The column name for the moderator in the data frame. 24 | #' @param data The dataframe where the columns from the formula can be found. 25 | #' @param random This variable is used to denote the data frame will be 26 | #' randomize by row, as part of the \code{boot} library. 27 | #' @keywords mediation, regression, indirect effect 28 | #' @export 29 | #' @examples 30 | #' indirectmed2("Q31 ~ Q151*Q121", "Q41 ~ Q151 + Q31", 31 | #' "Q11 ~ Q151 + Q31 + Q41", mtcars) 32 | #' @export 33 | 34 | indirectmed2_moda <- function(formula2, formula3, 35 | formula4, x, m1, m2, mod, df, random) { 36 | d = df[random, ] #randomize by row 37 | 38 | #figure out x categorical 39 | if (is.factor(df[ , x])){ 40 | xcat = T 41 | levelsx = paste(x, levels(df[, x])[-1], sep = "") 42 | } else { xcat = F } 43 | 44 | #run the models 45 | model2 = lm(formula2, data = d) 46 | model2.1 = lm(gsub(mod, "lowMod", formula2), data = d) 47 | model2.2 = lm(gsub(mod, "highMod", formula2), data = d) 48 | model3 = lm(formula3, data = d) 49 | model4 = lm(formula4, data = d) 50 | 51 | if (xcat == F){ #run this with continuous X 52 | 53 | #relevant coefficients 54 | a1_avg = coef(model2)[x] 55 | a1_low = coef(model2.1)[x] 56 | a1_high = coef(model2.2)[x] 57 | b1 = coef(model4)[m1] 58 | a2 = coef(model3)[x] 59 | b2 = coef(model4)[m2] 60 | d21 = coef(model3)[m1] 61 | 62 | #reporting 63 | indirect1_avg = a1_avg*b1 64 | indirect1_low = a1_low*b1 65 | indirect1_high = a1_high*b1 66 | indirect2 = a2*b2 67 | indirect3_avg = a1_avg*d21*b2 68 | indirect3_low = a1_low*d21*b2 69 | indirect3_high = a1_high*d21*b2 70 | 71 | } else { 72 | 73 | #figure out all the labels for X 74 | levelsx = paste(x, levels(df[, x])[-1], sep = "") 75 | indirect1_avg = NA; indirect1_low = NA; indirect1_high = NA; 76 | indirect2 = NA; indirect3_avg = NA; indirect3_low = NA; indirect3_high = NA 77 | 78 | #loop over that to figure out sobel and reporting 79 | for (i in 1:length(levelsx)){ 80 | 81 | #relevant coefficients 82 | a1_avg = coef(model2)[levelsx[i]] 83 | a1_low = coef(model2.1)[levelsx[i]] 84 | a1_high = coef(model2.2)[levelsx[i]] 85 | b1 = coef(model4)[m1] 86 | a2 = coef(model3)[levelsx[i]] 87 | b2 = coef(model4)[m2] 88 | d21 = coef(model3)[m1] 89 | 90 | #reporting 91 | indirect1_avg[i] = a1_avg*b1 92 | indirect1_low[i] = a1_low*b1 93 | indirect1_high[i] = a1_high*b1 94 | indirect2[i] = a2*b2 95 | indirect3_avg[i] = a1_avg*d21*b2 96 | indirect3_low[i] = a1_low*d21*b2 97 | indirect3_high[i] = a1_high*d21*b2 98 | 99 | } #close for loop 100 | } #close else x is categorical 101 | 102 | return(c(indirect1_avg = indirect1_avg, 103 | indirect1_low = indirect1_low, 104 | indirect1_high = indirect1_high, 105 | indirect2 = indirect2, 106 | indirect3_avg = indirect3_avg, 107 | indirect3_low = indirect3_low, 108 | indirect3_high = indirect3_high)) 109 | } 110 | 111 | #' @rdname indirectmed2_moda 112 | #' @export 113 | -------------------------------------------------------------------------------- /R/mediation1.R: -------------------------------------------------------------------------------- 1 | #' Simple Mediation 2 | #' 3 | #' This function runs a complete simple mediation analysis with one 4 | #' mediator, similiar to model 4 in PROCESS by A. Hayes (2013). 5 | #' As part of the output, you will find data screening, 6 | #' all three models used in the traditional Baron and 7 | #' Kenny (1986) steps, total/direct/indirect effects, the z-score and p-value 8 | #' for the Aroian Sobel test, and the bootstrapped confidence interval 9 | #' for the indirect effect. 10 | #' 11 | #' @param y The dependent variable column name from your dataframe. 12 | #' @param x The independent variable column name from your dataframe. This column 13 | #' will be treated as X in mediation or moderation models, please see 14 | #' diagrams online for examples. 15 | #' @param m The mediator for your model, as this model only includes one mediator. 16 | #' @param cvs The covariates you would like to include in the model. 17 | #' Use a \code{c()} concatenated vector to use multiple covariates. 18 | #' @param df The dataframe where the columns from the formula can be found. 19 | #' Note that only the columns used in the analysis will be data screened. 20 | #' @param with_out A logical value where you want to keep the outliers in 21 | #' model \code{TRUE} or exclude them from the model \code{FALSE}. 22 | #' @param nboot A numeric value indicating the number of bootstraps you would like to complete. 23 | #' @param ci_type choose type of cis you want 24 | #' @param conf_level A numeric value indicating the confidence interval width for the boostrapped confidence interval. 25 | #' @keywords mediation, moderation, regression, data screening, bootstrapping 26 | #' @export 27 | #' @examples 28 | #' mediation1(y = "cyl", x = "mpg", m = "disp", 29 | #' cvs = c("drat", "gear"), df = mtcars) 30 | #' @export 31 | 32 | mediation1 = function(y, x, m, cvs = NULL, df, with_out = T, 33 | nboot = 1000, ci_type=c("norm", "basic", "perc", "stud"), conf_level = .95) { 34 | 35 | require(boot) 36 | 37 | #stop if Y is categorical 38 | if (is.factor(df[ , y])){stop("Y should not be a categorical variable. Log regression options are coming soon.")} 39 | 40 | #stop if M is categorical 41 | if (is.factor(df[ , m])){stop("M should not be a categorial variable.")} 42 | 43 | #figure out if X is categorical 44 | if (is.factor(df[ , x])){xcat = TRUE} else {xcat = FALSE} 45 | 46 | #first create the full formula for data screening 47 | allformulas = createformula(y = y, x = x, m = m, 48 | cvs = cvs, type = "mediation1") 49 | 50 | #then do data screening 51 | screen = datascreen(allformulas$eq3, df, with_out) 52 | 53 | #take out outlines and create finaldata 54 | if (with_out == F) { finaldata = subset(screen$fulldata, totalout < 2) } else { finaldata = screen$fulldata } 55 | 56 | model1 = lm(allformulas$eq1, data = finaldata) #c path 57 | model2 = lm(allformulas$eq2, data = finaldata) #a path 58 | model3 = lm(allformulas$eq3, data = finaldata) #b c' paths 59 | 60 | if (xcat == F){ #run this with continuous X 61 | #aroian sobel 62 | a = coef(model2)[x] 63 | b = coef(model3)[m] 64 | SEa = summary(model2)$coefficients[x,2] 65 | SEb = summary(model3)$coefficients[m,2] 66 | zscore = (a*b)/(sqrt((b^2*SEa^2)+(a^2*SEb^2)+(SEa^2*SEb^2))) 67 | pvalue = pnorm(abs(zscore), lower.tail = F)*2 68 | 69 | #reporting 70 | total = coef(model1)[x] #c path 71 | direct = coef(model3)[x] #c' path 72 | indirect = a*b 73 | 74 | } else { 75 | 76 | #figure out all the labels for X 77 | levelsx = paste(x, levels(df[, x])[-1], sep = "") 78 | total = NA; indirect = NA; direct = NA; zscore = NA; pvalue = NA 79 | 80 | #loop over that to figure out sobel and reporting 81 | for (i in 1:length(levelsx)){ 82 | 83 | #aroian sobel 84 | a = coef(model2)[levelsx[i]] 85 | b = coef(model3)[m] 86 | SEa = summary(model2)$coefficients[levelsx[i],2] 87 | SEb = summary(model3)$coefficients[m,2] 88 | zscore[i] = (a*b)/(sqrt((b^2*SEa^2)+(a^2*SEb^2)+(SEa^2*SEb^2))) 89 | pvalue[i] = pnorm(abs(zscore[i]), lower.tail = F)*2 90 | 91 | #reporting 92 | total[i] = coef(model1)[levelsx[i]] #c path 93 | direct[i] = coef(model3)[levelsx[i]] #c' path 94 | indirect[i] = a*b 95 | 96 | } #close for loop 97 | } #close else x is categorical 98 | 99 | bootresults = boot(data = finaldata, 100 | statistic = indirectmed, 101 | formula2 = allformulas$eq2, 102 | formula3 = allformulas$eq3, 103 | x = x, 104 | med.var = m, 105 | R = nboot) 106 | 107 | if (xcat == F) { #run this if X is continuous 108 | bootci = boot.ci(bootresults, 109 | conf = conf_level, 110 | type = ci_type) 111 | } else { 112 | bootci = list() 113 | for (i in 1:length(levelsx)){ 114 | bootci[[i]] = boot.ci(bootresults, 115 | conf = conf_level, 116 | type = ci_type, 117 | index = i) 118 | names(bootci)[[i]] = levelsx[[i]] 119 | } #close for loop 120 | } #close else statement 121 | 122 | triangle = draw.med(model1, model2, model3, y, x, m, finaldata) 123 | 124 | return(list("datascreening" = screen, 125 | "model1" = model1, 126 | "model2" = model2, 127 | "model3" = model3, 128 | "total.effect" = total, 129 | "direct.effect" = direct, 130 | "indirect.effect" = indirect, 131 | "z.score" = zscore, 132 | "p.value" = pvalue, 133 | "boot.results" = bootresults, 134 | "boot.ci" = bootci, 135 | "diagram" = triangle 136 | )) 137 | } 138 | 139 | #' @rdname mediation1 140 | #' @export 141 | -------------------------------------------------------------------------------- /R/mediation2.R: -------------------------------------------------------------------------------- 1 | #' Serial Mediation with Two Mediators 2 | #' 3 | #' This function runs a complete serial mediation analysis with two 4 | #' mediators, similiar to model 6 in PROCESS by A. Hayes (2013). 5 | #' As part of the output, you will find data screening, 6 | #' all three models used in the traditional Baron and 7 | #' Kenny (1986) steps, total/direct/indirect effects, the z-score and p-value 8 | #' for the Aroian Sobel test, and the bootstrapped confidence interval 9 | #' for the indirect effect. 10 | #' 11 | #' @param y The dependent variable column name from your dataframe. 12 | #' @param x The independent variable column name from your dataframe. This column 13 | #' will be treated as X in mediation or moderation models, please see 14 | #' diagrams online for examples. 15 | #' @param m1 The first mediator for your model. 16 | #' @param m2 The second mediator for your model. 17 | #' @param cvs The covariates you would like to include in the model. 18 | #' Use a \code{c()} concatenated vector to use multiple covariates. 19 | #' @param df The dataframe where the columns from the formula can be found. 20 | #' Note that only the columns used in the analysis will be data screened. 21 | #' @param with_out A logical value where you want to keep the outliers in 22 | #' model \code{TRUE} or exclude them from the model \code{FALSE}. 23 | #' @param nboot A numeric value indicating the number of bootstraps you would like to complete. 24 | #' @param conf_level A numeric value indicating the confidence interval width for the boostrapped confidence interval. 25 | #' @keywords mediation, regression, data screening, bootstrapping 26 | #' @export 27 | #' @examples 28 | #' mediation2(y = "Q11", x = "Q151", m1 = "Q31", m2 = "Q41", 29 | #' cvs = c("Q121"), df = mediation2_data, nboot = 1000, with_out = T, 30 | #' conf_level = .95) 31 | #' @export 32 | 33 | mediation2 = function(y, x, m1, m2, cvs = NULL, df, with_out = T, 34 | nboot = 1000, conf_level = .95) { 35 | 36 | require(boot) 37 | 38 | #stop if Y is categorical 39 | if (is.factor(df[ , y])){stop("Y should not be a categorical variable. Log regression options are coming soon.")} 40 | 41 | #stop if M is categorical 42 | if (is.factor(df[ , m1])){stop("M1 should not be a categorial variable.")} 43 | if (is.factor(df[ , m2])){stop("M2 should not be a categorial variable.")} 44 | 45 | #figure out if X is categorical 46 | if (is.factor(df[ , x])){xcat = TRUE} else {xcat = FALSE} 47 | 48 | #first create the full formula for data screening 49 | allformulas = createformula(y = y, x = x, m = m1, 50 | m2 = m2, cvs = cvs, type = "mediation2") 51 | 52 | #then do data screening 53 | screen = datascreen(allformulas$eq4, df, with_out) 54 | 55 | #take out outlines and create finaldata 56 | if (with_out == F) { finaldata = subset(screen$fulldata, totalout < 2) } else { finaldata = screen$fulldata } 57 | 58 | model1 = lm(allformulas$eq1, data = finaldata) #c path 59 | model2 = lm(allformulas$eq2, data = finaldata) #a1 path 60 | model3 = lm(allformulas$eq3, data = finaldata) #a2 d21 path 61 | model4 = lm(allformulas$eq4, data = finaldata) #b2 c' paths 62 | 63 | if (xcat == F){ #run this with continuous X 64 | 65 | #relevant coefficients 66 | a1 = coef(model2)[x] 67 | b1 = coef(model4)[m1] 68 | a2 = coef(model3)[x] 69 | b2 = coef(model4)[m2] 70 | d21 = coef(model3)[m1] 71 | 72 | #reporting 73 | total = coef(model1)[x] #c path 74 | direct = coef(model4)[x] #c' path 75 | indirect1 = a1*b1 76 | indirect2 = a2*b2 77 | indirect3 = a1*d21*b2 78 | 79 | } else { 80 | 81 | #figure out all the labels for X 82 | levelsx = paste(x, levels(df[, x])[-1], sep = "") 83 | total = NA; indirect1 = NA; indirect2 = NA; indirect3 = NA 84 | direct = NA; zscore = NA; pvalue = NA 85 | 86 | #loop over that to figure out sobel and reporting 87 | for (i in 1:length(levelsx)){ 88 | 89 | #relevant coefficients 90 | a1 = coef(model2)[levelsx[i]] 91 | b1 = coef(model4)[m1] 92 | a2 = coef(model3)[levelsx[i]] 93 | b2 = coef(model4)[m2] 94 | d21 = coef(model3)[m1] 95 | 96 | #reporting 97 | total[i] = coef(model1)[levelsx[i]] #c path 98 | direct[i] = coef(model4)[levelsx[i]] #c' path 99 | indirect1[i] = a1*b1 100 | indirect2[i] = a2*b2 101 | indirect3[i] = a1*d21*b2 102 | 103 | } #close for loop 104 | } #close else x is categorical 105 | 106 | bootresults = boot(data = finaldata, 107 | statistic = indirectmed2, 108 | formula2 = allformulas$eq2, 109 | formula3 = allformulas$eq3, 110 | formula4 = allformulas$eq4, 111 | x = x, 112 | m1 = m1, 113 | m2 = m2, 114 | R = nboot) 115 | 116 | if (xcat == F) { #run this if X is continuous 117 | bootci = list() 118 | 119 | for (i in 1:length(bootresults$t0)) { 120 | 121 | bootci[[i]] = boot.ci(bootresults, 122 | conf = conf_level, 123 | type = "norm", 124 | index = i) 125 | names(bootci)[[i]] = paste(names(bootresults$t0)[[i]], ".", i, sep = "") 126 | } 127 | 128 | } else { 129 | bootci = list() 130 | sim = 1 131 | for (i in 1:length(levelsx)){ #loop over categorical x 132 | for (r in 1:length(bootresults$t0)) { #loop over multiple bootstraps 133 | 134 | bootci[[sim]] = boot.ci(bootresults, 135 | conf = conf_level, 136 | type = "norm", 137 | index = sim) 138 | 139 | names(bootci)[[sim]] = paste(levelsx[[i]], ".", names(bootresults$t0)[[r]], sep = "") 140 | sim = sim + 1 141 | } #close boot index 142 | 143 | } #close levels index 144 | 145 | } #close else statement 146 | 147 | return(list("datascreening" = screen, 148 | "model1" = model1, 149 | "model2" = model2, 150 | "model3" = model3, 151 | "model4" = model4, 152 | "total.effect" = total, 153 | "direct.effect" = direct, 154 | "indirect.effect1" = indirect1, 155 | "indirect.effect2" = indirect2, 156 | "indirect.effect3" = indirect3, 157 | "boot.results" = bootresults, 158 | "boot.ci" = bootci 159 | )) 160 | } 161 | 162 | #' @rdname mediation2 163 | #' @export 164 | -------------------------------------------------------------------------------- /R/mediation2_data.R: -------------------------------------------------------------------------------- 1 | #' Mediation 2 Data 2 | #' 3 | #' Dataset for use in \code{\link{mediation2}} example in MeMoBootR. 4 | #' These items were taken from student evaluations of teachers with 5 | #' 15 questions. ID represents a unique ID for each rating. 6 | #' 7 | #' @docType data 8 | #' 9 | #' @usage data(mediation2_data) 10 | #' 11 | #' @format A data frame of student evaluation ratings 12 | #' 13 | #' @keywords datasets 14 | #' 15 | "mediation2_data" 16 | -------------------------------------------------------------------------------- /R/mediation2_moda.R: -------------------------------------------------------------------------------- 1 | #' Two Mediations with Moderation on Path A 2 | #' 3 | #' This function runs a serial mediation analysis with two mediators 4 | #' (model 6) with an added moderation on path a (like model 7) 5 | #' using the model numbers from A. Hayes (2013). 6 | #' As part of the output, you will find data screening, 7 | #' all model outputs used in the traditional Baron and 8 | #' Kenny (1986) steps, total/direct/indirect effects, 9 | #' the z-score and p-value 10 | #' for the Aroian Sobel test, and the bootstrapped confidence interval 11 | #' for the indirect effect. These are separated by simple slopes 12 | #' for the moderation part of the analysis. 13 | #' 14 | #' @param y The dependent variable column name from your dataframe. 15 | #' @param x The independent variable column name from your dataframe. This column 16 | #' will be treated as X in mediation or moderation models, please see 17 | #' diagrams online for examples. 18 | #' @param m1 The first mediator for your model. 19 | #' @param m2 The second mediator for your model. 20 | #' @param cvs The covariates you would like to include in the model. 21 | #' Use a \code{c()} concatenated vector to use multiple covariates. 22 | #' @param df The dataframe where the columns from the formula can be found. 23 | #' Note that only the columns used in the analysis will be data screened. 24 | #' @param with_out A logical value where you want to keep the outliers in 25 | #' model \code{TRUE} or exclude them from the model \code{FALSE}. 26 | #' @param nboot A numeric value indicating the number of bootstraps you would like to complete. 27 | #' @param conf_level A numeric value indicating the confidence interval width for the boostrapped confidence interval. 28 | #' @keywords mediation, regression, data screening, bootstrapping 29 | #' @export 30 | #' @examples 31 | #' mediation2(y = "Q11", x = "Q151", m1 = "Q31", m2 = "Q41", mod = "Q121", 32 | #' cvs = NULL, df = mediation2_data, nboot = 1000, with_out = T, 33 | #' conf_level = .95) 34 | #' @export 35 | 36 | mediation2_moda <- function(y, x, m1, m2, mod, cvs = NULL, df, with_out = T, 37 | nboot = 1000, conf_level = .95) { 38 | 39 | require(boot) 40 | 41 | #stop if Y is categorical 42 | if (is.factor(df[ , y])){stop("Y should not be a categorical variable. Log regression options are coming soon.")} 43 | 44 | #stop if M is categorical 45 | if (is.factor(df[ , m1])){stop("M1 should not be a categorial variable.")} 46 | if (is.factor(df[ , m2])){stop("M2 should not be a categorial variable.")} 47 | 48 | #stop if W moderator is categorical 49 | if (is.factor(df[ , mod])){stop("Moderator should not be a categorial variable (at the moment).")} 50 | 51 | #figure out if X is categorical 52 | if (is.factor(df[ , x])){xcat = TRUE} else {xcat = FALSE} 53 | 54 | #first create the full formula for data screening 55 | allformulas <- createformula(y = y, x = x, m = m1, 56 | m2 = m2, mod = mod, cvs = cvs, type = "mediation2_moda") 57 | 58 | #then do data screening, include moderator 59 | screen <- datascreen(paste(allformulas$eq4, "+", mod, sep = " "), df, with_out) 60 | 61 | #take out outlines and create finaldata 62 | if (with_out == F) { finaldata = subset(screen$fulldata, totalout < 2) } else { finaldata = screen$fulldata } 63 | 64 | #center all the variables otherwise makes no sense 65 | if (!is.factor(finaldata[ , x])){ finaldata[ , x] <- scale(finaldata[ , x], scale = F) } 66 | if (!is.factor(finaldata[ , m1])){ finaldata[ , m1] <- scale(finaldata[ , m1], scale = F) } 67 | if (!is.factor(finaldata[ , m2])){ finaldata[ , m2] <- scale(finaldata[ , m2], scale = F) } 68 | 69 | #create low and high moderation 70 | if (!is.factor(finaldata[ , mod])){ 71 | finaldata[ , mod] <- scale(finaldata[ , mod], scale = F) 72 | finaldata$lowMod = finaldata[ , mod] + sd(finaldata[ , mod]) 73 | finaldata$highMod = finaldata[ , mod] - sd(finaldata[ , mod]) 74 | } 75 | 76 | model1 = lm(allformulas$eq1, data = finaldata) #c path 77 | model2 = lm(allformulas$eq2, data = finaldata) #a1_avg path 78 | model3 = lm(allformulas$eq3, data = finaldata) #a2 d21 path 79 | model4 = lm(allformulas$eq4, data = finaldata) #b2 c' paths 80 | 81 | #moderation effects 82 | model2.1 = lm(allformulas$eq2.1, data = finaldata) #a1_low path 83 | model2.2 = lm(allformulas$eq2.2, data = finaldata) #a1_high path 84 | 85 | if (xcat == F){ #run this with continuous X 86 | 87 | #relevant coefficients 88 | a1_avg = coef(model2)[x] 89 | a1_low = coef(model2.1)[x] 90 | a1_high = coef(model2.2)[x] 91 | b1 = coef(model4)[m1] 92 | a2 = coef(model3)[x] 93 | b2 = coef(model4)[m2] 94 | d21 = coef(model3)[m1] 95 | 96 | #reporting 97 | total = coef(model1)[x] #c path 98 | direct = coef(model4)[x] #c' path 99 | indirect1_avg = a1_avg*b1 100 | indirect1_low = a1_low*b1 101 | indirect1_high = a1_high*b1 102 | indirect2 = a2*b2 103 | indirect3_avg = a1_avg*d21*b2 104 | indirect3_low = a1_low*d21*b2 105 | indirect3_high = a1_high*d21*b2 106 | 107 | } else { 108 | 109 | #figure out all the labels for X 110 | levelsx = paste(x, levels(df[, x])[-1], sep = "") 111 | total = NA; indirect1_avg = NA; indirect1_low = NA; indirect1_high = NA; 112 | indirect2 = NA; indirect3_avg = NA; indirect3_low = NA; indirect3_high = NA 113 | direct = NA; zscore = NA; pvalue = NA 114 | 115 | #loop over that to figure out sobel and reporting 116 | for (i in 1:length(levelsx)){ 117 | 118 | #relevant coefficients 119 | a1_avg = coef(model2)[levelsx[i]] 120 | a1_low = coef(model2.1)[levelsx[i]] 121 | a1_high = coef(model2.2)[levelsx[i]] 122 | b1 = coef(model4)[m1] 123 | a2 = coef(model3)[levelsx[i]] 124 | b2 = coef(model4)[m2] 125 | d21 = coef(model3)[m1] 126 | 127 | #reporting 128 | total[i] = coef(model1)[levelsx[i]] #c path 129 | direct[i] = coef(model4)[levelsx[i]] #c' path 130 | indirect1_avg[i] = a1_avg*b1 131 | indirect1_low[i] = a1_low*b1 132 | indirect1_high[i] = a1_high*b1 133 | indirect2[i] = a2*b2 134 | indirect3_avg[i] = a1_avg*d21*b2 135 | indirect3_low[i] = a1_low*d21*b2 136 | indirect3_high[i] = a1_high*d21*b2 137 | 138 | } #close for loop 139 | } #close else x is categorical 140 | 141 | bootresults <- boot(data = finaldata, 142 | statistic = indirectmed2_moda, 143 | formula2 = allformulas$eq2, 144 | formula3 = allformulas$eq3, 145 | formula4 = allformulas$eq4, 146 | x = x, 147 | m1 = m1, 148 | m2 = m2, 149 | mod = mod, 150 | R = nboot) 151 | 152 | if (xcat == F) { #run this if X is continuous 153 | bootci = list() 154 | 155 | for (i in 1:length(bootresults$t0)) { 156 | 157 | bootci[[i]] = boot.ci(bootresults, 158 | conf = conf_level, 159 | type = "norm", 160 | index = i) 161 | names(bootci)[[i]] = paste(names(bootresults$t0)[[i]], ".", i, sep = "") 162 | } 163 | 164 | } else { 165 | bootci = list() 166 | sim = 1 167 | for (i in 1:length(levelsx)){ #loop over categorical x 168 | for (r in 1:length(bootresults$t0)) { #loop over multiple bootstraps 169 | 170 | bootci[[sim]] = boot.ci(bootresults, 171 | conf = conf_level, 172 | type = "norm", 173 | index = sim) 174 | 175 | names(bootci)[[sim]] = paste(levelsx[[i]], ".", names(bootresults$t0)[[r]], sep = "") 176 | sim = sim + 1 177 | } #close boot index 178 | 179 | } #close levels index 180 | 181 | } #close else statement 182 | 183 | return(list("datascreening" = screen, 184 | "model1" = model1, 185 | "model2" = model2, 186 | "model2_low" = model2.1, 187 | "model2_high" = model2.2, 188 | "model3" = model3, 189 | "model4" = model4, 190 | "total.effect" = total, 191 | "direct.effect" = direct, 192 | "indirect.effect1_avg" = indirect1_avg, 193 | "indirect.effect1_low" = indirect1_low, 194 | "indirect.effect1_high" = indirect1_high, 195 | "indirect.effect2" = indirect2, 196 | "indirect.effect3_avg" = indirect3_avg, 197 | "indirect.effect3_low" = indirect3_low, 198 | "indirect.effect3_high" = indirect3_high, 199 | "boot.results" = bootresults, 200 | "boot.ci" = bootci 201 | )) 202 | } 203 | 204 | #' @rdname mediation2_moda 205 | #' @export 206 | -------------------------------------------------------------------------------- /R/moderation1.R: -------------------------------------------------------------------------------- 1 | #' Two Way Moderation 2 | #' 3 | #' This function runs a complete two way moderation analysis with one 4 | #' moderator, similiar to model 1 in PROCESS by A. Hayes (2013). 5 | #' As part of the output, you will find data screening, 6 | #' the overall model, and the simple slopes for X at each level of the moderator. 7 | #' X and M variables will be mean centered after data screening and 8 | #' before analysis to control for multicollinearity unless they are categorical. 9 | #' 10 | #' @param y The dependent variable column name from your dataframe. 11 | #' @param x The independent variable column name from your dataframe. This column 12 | #' will be treated as X in mediation or moderation models, please see 13 | #' diagrams online for examples. 14 | #' @param m The moderator for your model, as this model only includes one moderator. 15 | #' @param cvs The covariates you would like to include in the model. 16 | #' Use a \code{c()} concatenated vector to use multiple covariates. 17 | #' @param df The dataframe where the columns from the formula can be found. 18 | #' Note that only the columns used in the analysis will be data screened. 19 | #' @param with_out A logical value where you want to keep the outliers in 20 | #' model \code{TRUE} or exclude them from the model \code{FALSE}. 21 | #' @keywords mediation, moderation, regression, data screening, bootstrapping 22 | #' @export 23 | #' @examples 24 | #' states = as.data.frame(state.x77) 25 | #' moderation1(y = "Income", x = "Illiteracy", m = "Murder", 26 | #' cvs = c("Population", "Area"), df = states) 27 | #' @export 28 | 29 | moderation1 = function(y, x, m, cvs = NULL, df, with_out = T) { 30 | 31 | #graph information 32 | require(ggplot2) 33 | cleanup = theme(panel.grid.major = element_blank(), 34 | panel.grid.minor = element_blank(), 35 | panel.background = element_blank(), 36 | axis.line.x = element_line(color = "black"), 37 | axis.line.y = element_line(color = "black"), 38 | legend.key = element_rect(fill = "white"), 39 | text = element_text(size = 15)) 40 | 41 | #stop if Y is categorical 42 | if (is.factor(df[ , y])){stop("Y should not be a categorical variable. Log regression options are coming soon.")} 43 | 44 | #stop if X is categorical 45 | if (is.factor(df[ , x])){stop("X should not be categorical, please put categorical predictors as M (or use ANOVA for double categorical variables).")} 46 | 47 | #first create the full formula for data screening 48 | allformulas = createformula(y = y, x = x, m = m, 49 | cvs = cvs, type = "moderation1") 50 | 51 | #then do data screening 52 | screen = datascreen(allformulas$eq1, df, with_out) 53 | 54 | #take out outlines and create finaldata 55 | if (with_out == F) { finaldata = subset(screen$fulldata, totalout < 2) } else { finaldata = screen$fulldata } 56 | 57 | #center x and m in the finaldata 58 | if (!is.factor(finaldata[ , x])){finaldata[ , x] = scale(finaldata[ , x], scale = F)} 59 | if (!is.factor(finaldata[ , m])){finaldata[ , m] = scale(finaldata[ , m], scale = F)} 60 | 61 | model1 = lm(allformulas$eq1, data = finaldata) #full model 62 | 63 | if (!is.factor(finaldata[ , m])){ #run this on categorical M 64 | #create simple slopes 65 | finaldata$lowM = finaldata[ , m] + sd(finaldata[ , m]) 66 | finaldata$highM = finaldata[ , m] - sd(finaldata[ , m]) 67 | 68 | model1low = lm(allformulas$eq2, data = finaldata) #low simple slope 69 | model1high = lm(allformulas$eq3, data = finaldata) #high simple slope 70 | 71 | simslopes = paste("At low levels of ", m, ", you see that every unit increase in ", 72 | x, " predicts ", round(coef(model1low)[x],2), " unit change in ", y, 73 | ". \n\nAt average levels of ", m, ", you see that every unit increase in ", 74 | x, " predicts ", round(coef(model1)[x],2), " unit change in ", y, 75 | ". \n\nAt high levels of ", m, ", you see that every unit increase in ", 76 | x, " predicts ", round(coef(model1high)[x],2), " unit change in ", y, 77 | ".", sep = "") 78 | 79 | lowlabel = paste("-1SD ", m, sep = "") 80 | avglabel = paste("Average ", m, sep = "") 81 | highlabel = paste("+1SD ", m, sep = "") 82 | 83 | plot_sim = ggplot(finaldata, aes(finaldata[ , x],finaldata[ , y])) + 84 | xlab(x) + 85 | ylab(y) + 86 | geom_point() + 87 | scale_size_continuous(guide = FALSE) + 88 | geom_abline(aes(intercept = coef(model1low)["(Intercept)"], slope = coef(model1low)[x], linetype = lowlabel)) + 89 | geom_abline(aes(intercept = coef(model1)["(Intercept)"], slope = coef(model1)[x], linetype = avglabel)) + 90 | geom_abline(aes(intercept = coef(model1high)["(Intercept)"], slope = coef(model1high)[x], linetype = highlabel)) + 91 | scale_linetype_manual(values = c("dotted", "dashed", "solid"), 92 | breaks = c(lowlabel, avglabel, highlabel), 93 | name = "Simple Slope") + 94 | coord_cartesian(xlim = c(min(finaldata[, x]), max(finaldata[, x])), 95 | ylim = c(min(finaldata[, y]), max(finaldata[, y]))) + 96 | cleanup + 97 | NULL 98 | 99 | return(list("datascreening" = screen, 100 | "model1" = model1, 101 | "model1low" = model1low, 102 | "model1high" = model1high, 103 | "interpretation" = simslopes, 104 | "graphslopes" = plot_sim)) 105 | 106 | } else { #run this on categorical M 107 | 108 | #figure out simple slopes 109 | if (!is.null(cvs)) { 110 | eqsim = paste(y, "~", x, "+", paste(cvs, collapse = " + "), sep = " ") 111 | } else { 112 | eqsim = paste(y, "~", x, sep = " ") 113 | } 114 | 115 | 116 | simmodels = by(finaldata, finaldata[ , m], function(finaldata) lm(eqsim, data = finaldata)) 117 | 118 | simslopes = "" 119 | for (i in levels(finaldata[ , m])) { 120 | simslopes = paste(simslopes, 121 | "At ", i, " levels of ", m, ", you see that every unit increase in ", 122 | x, " predicts ", round(simmodels[[i]]$coefficients[x], 2), 123 | " unit change in ", y, ". \n\n", sep = "") 124 | } 125 | 126 | plot_sim = ggplot(finaldata, aes(finaldata[ , x],finaldata[ , y], 127 | color = finaldata[ , m])) + 128 | xlab(x) + 129 | ylab(y) + 130 | geom_point() + 131 | geom_smooth(method=lm, aes(fill=finaldata[ , m])) + 132 | coord_cartesian(xlim = c(min(finaldata[, x]), max(finaldata[, x])), 133 | ylim = c(min(finaldata[, y]), max(finaldata[, y]))) + 134 | labs(fill = m, color = m) + 135 | cleanup + 136 | NULL 137 | 138 | return(list("datascreening" = screen, 139 | "model1" = model1, 140 | "slopemodels" = simmodels, 141 | "interpretation" = simslopes, 142 | "graphslopes" = plot_sim)) 143 | 144 | } #close categorical mediation 145 | 146 | } 147 | 148 | #' @rdname moderation1 149 | #' @export 150 | -------------------------------------------------------------------------------- /R/moderation2.R: -------------------------------------------------------------------------------- 1 | #' Double Two-Way Moderation 2 | #' 3 | #' This function runs a complete double two-way moderation analysis with two 4 | #' moderators, similiar to model 2 in PROCESS by A. Hayes (2013). 5 | #' As part of the output, you will find data screening, 6 | #' the overall model, and the simple slopes for X at each level of the moderator. 7 | #' X and M variables will be mean centered after data screening and 8 | #' before analysis to control for multicollinearity unless they are categorical. 9 | #' 10 | #' @param y The dependent variable column name from your dataframe. 11 | #' @param x The independent variable column name from your dataframe. This column 12 | #' will be treated as X in mediation or moderation models, please see 13 | #' diagrams online for examples. 14 | #' @param m1 The first moderator for your model. 15 | #' @param m2 The second moderator for your model. 16 | #' @param cvs The covariates you would like to include in the model. 17 | #' Use a \code{c()} concatenated vector to use multiple covariates. 18 | #' @param df The dataframe where the columns from the formula can be found. 19 | #' Note that only the columns used in the analysis will be data screened. 20 | #' @param with_out A logical value where you want to keep the outliers in 21 | #' model \code{TRUE} or exclude them from the model \code{FALSE}. 22 | #' @keywords mediation, moderation, regression, data screening, bootstrapping 23 | #' @export 24 | #' @examples 25 | #' states = as.data.frame(state.x77) 26 | #' moderation2(y = "Income", x = "Illiteracy", m1 = "Murder", 27 | #' m2 = "Population", df = states) 28 | #' @export 29 | 30 | moderation2 = function(y, x, m1, m2, cvs = NULL, df, with_out = T) { 31 | 32 | #graph information 33 | require(ggplot2) 34 | cleanup = theme(panel.grid.major = element_blank(), 35 | panel.grid.minor = element_blank(), 36 | panel.background = element_blank(), 37 | axis.line.x = element_line(color = "black"), 38 | axis.line.y = element_line(color = "black"), 39 | legend.key = element_rect(fill = "white"), 40 | text = element_text(size = 15)) 41 | 42 | #stop if Y is categorical 43 | if (is.factor(df[ , y])){stop("Y should not be a categorical variable. Log regression options are coming soon.")} 44 | 45 | #stop if X is categorical 46 | if (is.factor(df[ , x])){stop("X should not be categorical, please put categorical predictors as M (or use ANOVA for double categorical variables).")} 47 | 48 | #first create the full formula for data screening 49 | allformulas = createformula(y = y, x = x, m = m1, 50 | m2 = m2, cvs = cvs, type = "moderation2") 51 | 52 | #then do data screening 53 | screen = datascreen(allformulas$eq1, df, with_out) 54 | 55 | #take out outlines and create finaldata 56 | if (with_out == F) { finaldata = subset(screen$fulldata, totalout < 2) } else { finaldata = screen$fulldata } 57 | 58 | #center x and m in the finaldata, create simple slopes for continuous variables 59 | if (!is.factor(finaldata[ , x])){finaldata[ , x] = scale(finaldata[ , x], scale = F)} 60 | if (!is.factor(finaldata[ , m1])){ 61 | finaldata[ , m1] = scale(finaldata[ , m1], scale = F) 62 | finaldata$lowM1 = finaldata[ , m1] + sd(finaldata[ , m1]) 63 | finaldata$highM1 = finaldata[ , m1] - sd(finaldata[ , m1]) 64 | } 65 | if (!is.factor(finaldata[ , m2])){ 66 | finaldata[ , m2] = scale(finaldata[ , m2], scale = F) 67 | finaldata$lowM2 = finaldata[ , m2] + sd(finaldata[ , m2]) 68 | finaldata$highM2 = finaldata[ , m2] - sd(finaldata[ , m2]) 69 | } 70 | 71 | model1 = lm(allformulas$eq1, data = finaldata) #full model 72 | 73 | #run simple slopes for all continuous categorical combinations 74 | 75 | ####both continuous#### 76 | if (!is.factor(finaldata[ , m1]) & !is.factor(finaldata[ , m2])){ 77 | 78 | model1.1 = lm(allformulas$eq1.1, data = finaldata) 79 | model1.2 = lm(allformulas$eq1.2, data = finaldata) 80 | model2 = lm(allformulas$eq2, data = finaldata) 81 | model2.1 = lm(allformulas$eq2.1, data = finaldata) 82 | model2.2 = lm(allformulas$eq2.2, data = finaldata) 83 | model3 = lm(allformulas$eq3, data = finaldata) 84 | model3.1 = lm(allformulas$eq3.1, data = finaldata) 85 | model3.2 = lm(allformulas$eq3.2, data = finaldata) 86 | 87 | simslopes = data.frame(row.names = c(paste("Low",m1), 88 | paste("Average",m1), 89 | paste("High",m1)), 90 | "Low" = c(coef(model2.1)[x], coef(model1.1)[x], coef(model3.1)[x]), 91 | "Average" = c(coef(model2)[x], coef(model1)[x], coef(model3)[x]), 92 | "High" = c(coef(model2.2)[x], coef(model1.2)[x], coef(model3.2)[x]) 93 | ) 94 | colnames(simslopes) = c(paste("Low", m2), paste("Average", m2), paste("High", m2)) 95 | 96 | #graphs 97 | lowlabel = paste("-1SD ", m2, sep = "") 98 | avglabel = paste("Average ", m2, sep = "") 99 | highlabel = paste("+1SD ", m2, sep = "") 100 | 101 | #low m1 102 | plot_sim_low = ggplot(finaldata, aes(finaldata[ , x],finaldata[ , y])) + 103 | xlab(x) + 104 | ylab(y) + 105 | geom_point(alpha = .3) + 106 | scale_size_continuous(guide = FALSE) + 107 | geom_abline(aes(intercept = coef(model2.1)["(Intercept)"], slope = coef(model2.1)[x], linetype = lowlabel)) + 108 | geom_abline(aes(intercept = coef(model2)["(Intercept)"], slope = coef(model2)[x], linetype = avglabel)) + 109 | geom_abline(aes(intercept = coef(model2.2)["(Intercept)"], slope = coef(model2.2)[x], linetype = highlabel)) + 110 | scale_linetype_manual(values = c("dotted", "dashed", "solid"), 111 | breaks = c(lowlabel, avglabel, highlabel), 112 | name = "Simple Slope") + 113 | coord_cartesian(xlim = c(min(finaldata[, x]), max(finaldata[, x])), 114 | ylim = c(min(finaldata[, y]), max(finaldata[, y]))) + 115 | cleanup + 116 | NULL 117 | 118 | #average m1 119 | plot_sim_average = ggplot(finaldata, aes(finaldata[ , x],finaldata[ , y])) + 120 | xlab(x) + 121 | ylab(y) + 122 | geom_point(alpha = .3) + 123 | scale_size_continuous(guide = FALSE) + 124 | geom_abline(aes(intercept = coef(model1.1)["(Intercept)"], slope = coef(model1.1)[x], linetype = lowlabel)) + 125 | geom_abline(aes(intercept = coef(model1)["(Intercept)"], slope = coef(model1)[x], linetype = avglabel)) + 126 | geom_abline(aes(intercept = coef(model1.2)["(Intercept)"], slope = coef(model1.2)[x], linetype = highlabel)) + 127 | scale_linetype_manual(values = c("dotted", "dashed", "solid"), 128 | breaks = c(lowlabel, avglabel, highlabel), 129 | name = "Simple Slope") + 130 | coord_cartesian(xlim = c(min(finaldata[, x]), max(finaldata[, x])), 131 | ylim = c(min(finaldata[, y]), max(finaldata[, y]))) + 132 | cleanup + 133 | NULL 134 | 135 | #high m1 136 | plot_sim_high = ggplot(finaldata, aes(finaldata[ , x],finaldata[ , y])) + 137 | xlab(x) + 138 | ylab(y) + 139 | geom_point(alpha = .3) + 140 | scale_size_continuous(guide = FALSE) + 141 | geom_abline(aes(intercept = coef(model3.1)["(Intercept)"], slope = coef(model3.1)[x], linetype = lowlabel)) + 142 | geom_abline(aes(intercept = coef(model3)["(Intercept)"], slope = coef(model3)[x], linetype = avglabel)) + 143 | geom_abline(aes(intercept = coef(model3.2)["(Intercept)"], slope = coef(model3.2)[x], linetype = highlabel)) + 144 | scale_linetype_manual(values = c("dotted", "dashed", "solid"), 145 | breaks = c(lowlabel, avglabel, highlabel), 146 | name = "Simple Slope") + 147 | coord_cartesian(xlim = c(min(finaldata[, x]), max(finaldata[, x])), 148 | ylim = c(min(finaldata[, y]), max(finaldata[, y]))) + 149 | cleanup + 150 | NULL 151 | 152 | return(list("datascreening" = screen, 153 | "avgm1_avgm2" = model1, 154 | "avgm1_lowm2" = model1.1, 155 | "avgm1_highm2" = model1.2, 156 | "lowm1_avgm2" = model2, 157 | "lowm1_lowm2" = model2.1, 158 | "lowm1_highm2" = model2.2, 159 | "highm1_avgm2" = model3, 160 | "highm1_lowm2" = model3.1, 161 | "highm1_highm2" = model3.2, 162 | "interpretation" = simslopes, 163 | "lowm1_graph" = plot_sim_low, 164 | "avgm1_graph" = plot_sim_average, 165 | "highm1_graph" = plot_sim_high)) 166 | } 167 | 168 | ####m1 categorical, m2 continuous#### 169 | if (is.factor(finaldata[ , m1]) & !is.factor(finaldata[ , m2])){ 170 | return("Coming soon!") 171 | } 172 | 173 | ####m1 continous, m2 categorical#### 174 | if (!is.factor(finaldata[ , m1]) & is.factor(finaldata[ , m2])){ 175 | return("Coming soon!") 176 | } 177 | 178 | ####m1 categorical, m2 catorgical#### 179 | if (is.factor(finaldata[ , m1]) & is.factor(finaldata[ , m2])){ 180 | return("Coming soon!") 181 | } 182 | 183 | } 184 | 185 | #' @rdname moderation2 186 | #' @export 187 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MeMoBootR 2 | 3 | This package is in (ok fine somewhat) active development. I am working on updating as I go through the different models involved in mediation and moderation. You can check out videos / updates on my [YouTube channel](https://www.youtube.com/channel/UCMdihazndR0f9XBoSXWqnYg), as well as watching or starring the github repo. 4 | 5 | To install the package take the following steps: 6 | 7 | 1) Install `devtools` if you do not have it. `devtools` is a package that allows you to install packages from github. 8 | `install.packages("devtools")` 9 | 10 | 2) Install the `MeMoBootR` package by running the following: 11 | `devtools::install_github("doomlab/MeMoBootR")` 12 | 13 | 3) Load the library to get started! 14 | `library(MeMoBootR)` 15 | 16 | 4) Enjoy mediation and moderation complete with data screening. 17 | 18 | 5) Cite the package! 19 | `Buchanan, E.M. (2018). MeMoBootR [Computer Program]. Avaliable at: https://github.com/doomlab/MeMoBootR`. 20 | 21 | More tutorials, details, and other information added as I go. 22 | 23 | Many thanks to KD Valentine for the fantastic name suggestion. 24 | 25 | # Table of Possibilities 26 | 27 | |PROCESS| MeMoBootR | Label | Categorical X | Categorical M | 28 | | --- | --- | --- | --- | --- | 29 | | Model 1 | moderation1() | Two-way moderation | No | Yes | 30 | | Model 2 | moderation2() | Double Two-way moderation | No | Yes | 31 | | Model 4 | mediation1() | Simple mediation | Yes | No | 32 | | Model 6 | mediation2() | Serial mediation | Yes | No | 33 | | Model 6-7 Hybrid | mediation2_moda() | Serial Mediation with Moderator on A | Yes | No for mediators/moderators | 34 | 35 | - For moderation models with categorical variables, make those variables M, rather than X. For X and M categorical, use ANOVA (`ez` is a great package). 36 | - Mediation should allow for categorical X and M, just haven't gotten there yet. 37 | 38 | # Examples 39 | 40 | Head over to the [OSF Page](https://osf.io/ns6jz/) to view examples of the function in action. Included on the OSF page are youtube videos that explain the different functions and examples. Additionally, you can find information about the translation of the model numbers from PROCESSv3 to MeMoBootR. 41 | 42 | # Version Information 43 | Version: 0.0.0.7000 44 | - Adding serial mediation with a continuous moderator on the A path. Should be able to do all paths at some point. 45 | 46 | Version: 0.0.0.6001 47 | - Fixed bug with mediation1(), moderation1() that did not allow cvs to show up. 48 | 49 | Version: 0.0.0.6000 50 | - Added double two-way moderation - which is two two-way interactions with two moderators (model 2). 51 | - The next goals are to make mediation2 and moderation2 work for categorical variables over the next couple of weeks. 52 | 53 | Version: 0.0.0.5000 54 | - Added serial mediation with two mediators (model 6). The model can handle covariates and should be able to do categorical X. I will be testing categorical X more next week. 55 | 56 | Version: 0.0.0.4000 57 | - Added categorical moderators, where X is continuous, M can be categorical or continuous. Please note that it will not run with X categorical. (model 1 - moderation) 58 | 59 | Version: 0.0.0.3000 60 | - Added two way interactions (model 1 - moderation) 61 | - No good categorical options yet (i.e., it'll run but not what you want probably yet) 62 | - Updated data screening so it can handle categorical CV values across all analyses 63 | 64 | Version: 0.0.0.2000 65 | - Added diagram ability with `diagram` library (wouldn't mind help here, the diagrams for mediation are only ok) 66 | - Added ability for categorical X variables in simple mediation 67 | 68 | Version: 0.0.0.1000: 69 | - Initial build 70 | - Simple mediation with categorical variables added 71 | -------------------------------------------------------------------------------- /create git.R: -------------------------------------------------------------------------------- 1 | ##set up for github 2 | install.packages("roxygen2") 3 | 4 | ##set working direction to create stuff 5 | #setwd("~/Downloads") 6 | 7 | ##create the folder for everything 8 | devtools::create("MeMoBootR") 9 | 10 | ##open that folder 11 | ##create a man folder within the folder you just made 12 | ##empty R folder gets the function files 13 | ##fix the description file 14 | ##you can open this in R - edit the information in this file to be correct (use license() to get the current license) 15 | license() 16 | 17 | ##at the beginning of each function you add special code 18 | #' Name of the Function 19 | #' 20 | #' Description of the function 21 | #' @param several lines of this that describes the arguments so you put the argument name, then space, then describe the argument 22 | #' @keywords 23 | #' @export maybe leave blank 24 | #' @examples leave this blank 25 | #' now put in the examples here 26 | 27 | ##set your working directory to package file 28 | #setwd("~/OneDrive - Missouri State University/RESEARCH/2 projects/MeMoBootR") 29 | 30 | ##run this thing 31 | library(roxygen2) 32 | roxygen2::roxygenise() 33 | ##it searches through folder looks for description 34 | ##and create the Rd files and put into man folder 35 | 36 | ##Then you put it on git hub 37 | 38 | ##then run this to update 39 | devtools::install_github("doomlab/MeMoBootR") 40 | -------------------------------------------------------------------------------- /data/mediation2_data.Rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/data/mediation2_data.Rdata -------------------------------------------------------------------------------- /examples/MeMo Handout.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/MeMo Handout.docx -------------------------------------------------------------------------------- /examples/example_mediation1 cat.R: -------------------------------------------------------------------------------- 1 | ##An example of mediation 1 with categorical variables 2 | 3 | ##install if you need to 4 | devtools::install_github("doomlab/MeMoBootR") 5 | 6 | ##load the library 7 | library(MeMoBootR) 8 | 9 | data(mtcars) 10 | mtcars$cyl = as.factor(mtcars$cyl) 11 | 12 | saved = mediation1(y = "mpg", #DV 13 | x = "cyl", #IV 14 | m = "wt", #Mediator 15 | cvs = NULL, #Any covariates 16 | df = mtcars, #Dataframe 17 | with_out = T, #Not required but can change to F for no outliers 18 | nboot = 1000, #Number of bootstraps 19 | conf_level = .95 #CI width 20 | ) 21 | 22 | ####view data screening#### 23 | #outlier information is in the DF 24 | View(saved$datascreening$fulldata) 25 | 26 | #additivity 27 | saved$datascreening$correl 28 | 29 | #linearity 30 | saved$datascreening$linearity 31 | 32 | #normality 33 | saved$datascreening$normality 34 | 35 | #homogs 36 | saved$datascreening$homogen 37 | 38 | ####view the analysis#### 39 | summary(saved$model1) #c path 40 | summary(saved$model2) #a path 41 | summary(saved$model3) #b and c' path 42 | 43 | #X predicts Y total effects 44 | #4v6 b = -6.92, t(29) = -4.44, p < .001 45 | #4v8 b = -11.56, t(29) = -8.91, p < .001 46 | #interpretation difference between groups (X) on Y 47 | tapply(mtcars$mpg, mtcars$cyl, mean) 48 | 49 | #X predicts M 50 | #4v6 b = 0.83, t(29) = 2.73, p = .011 51 | #4v8 b = 1.71, t(29) = 6.75, p < .001 52 | tapply(mtcars$wt, mtcars$cyl,mean) 53 | 54 | #X predicts Y with M direct effects 55 | #4v6 b = -4.26, t(28) = -3.07, p = .005 56 | #4v8 b = -6.07, t(28) = -3.67, p < .001 57 | 58 | #M predicts Y with X 59 | #b = -3.21, t(28) = -4.25, p < .001 60 | 61 | #total, direct, indirect effects 62 | saved$total.effect; saved$direct.effect; saved$indirect.effect 63 | 64 | #Sobel test 65 | saved$z.score; saved$p.value 66 | 67 | #Z = -2.12, p = .034 68 | #Z = -3.45, p < .001 69 | 70 | #bootstrapped indirect 71 | saved$boot.results 72 | 73 | #bootstrapped CI 74 | saved$boot.ci 75 | 76 | #HEY I FIXED THIS! 77 | #indirect = -2.67, 95% CI[-4.58, -0.78] does not include zero, so mediation occurred 78 | #indirect = -5.49, 95% CI[-8.28, -2.62] does not include zero, so mediation occurred 79 | 80 | #diagram 81 | saved$diagram 82 | 83 | ####power#### 84 | library(pwr) 85 | ##power runs on cohen's f - not to be confused with anova f. 86 | ##take the R squared to convert 87 | R2 = .14 88 | feta = R2 / (1-R2) 89 | 90 | #u is df model, which is number of predictors 91 | #v is df error, but we are trying to figure out 92 | #sample size so we leave this one blank. 93 | #f2 is cohen f squared 94 | 95 | pwr.f2.test(u = 3, v = NULL, f2 = feta, sig.level = .05, power = .80) 96 | #remember that you need to add u + v to get final sample size 97 | -------------------------------------------------------------------------------- /examples/example_mediation1.R: -------------------------------------------------------------------------------- 1 | ##An example of mediation 1 2 | 3 | ##install if you need to 4 | devtools::install_github("doomlab/MeMoBootR") 5 | 6 | ##load the library 7 | library(MeMoBootR) 8 | 9 | saved = mediation1(y = "mpg", #DV 10 | x = "cyl", #IV 11 | m = "hp", #Mediator 12 | cvs = c("wt", "gear"), #Any covariates 13 | df = mtcars, #Dataframe 14 | with_out = T, #Not required but can change to F for no outliers 15 | nboot = 1000, #Number of bootstraps 16 | conf_level = .95 #CI width 17 | ) 18 | 19 | ####view data screening#### 20 | #outlier information is in the DF 21 | View(saved$datascreening$fulldata) 22 | 23 | #additivity 24 | saved$datascreening$correl 25 | 26 | #linearity 27 | saved$datascreening$linearity 28 | 29 | #normality 30 | saved$datascreening$normality 31 | 32 | #homogs 33 | saved$datascreening$homogen 34 | 35 | ####view the analysis#### 36 | summary(saved$model1) #c path 37 | summary(saved$model2) #a path 38 | summary(saved$model3) #b and c' path 39 | 40 | #X predicts Y total effects 41 | #c path b = -1.52, t(28) = -3.64, p = .001 42 | #F(3,28) = 46.53, p < .001, R2 = .83 43 | 44 | #X predicts M 45 | #a path b = 32.97, t(28) = 6.64, p < .001 46 | 47 | #X predicts Y with M direct effects 48 | #c' path b = -0.81, t(27) = -1.23, p = .231 49 | #M predicts Y with X 50 | #b path b = -0.02, t(27) = -1.38, p = .179 51 | 52 | #total, direct, indirect effects 53 | saved$total.effect; saved$direct.effect; saved$indirect.effect 54 | 55 | #Sobel test 56 | saved$z.score; saved$p.value 57 | 58 | #bootstrapped indirect 59 | saved$boot.results 60 | 61 | #bootstrapped CI 62 | saved$boot.ci 63 | 64 | #indirect = -0.72, SE = 0.52, 95% CI[-1.81, 0.22] 65 | 66 | ####power#### 67 | library(pwr) 68 | ##power runs on cohen's f - not to be confused with anova f. 69 | ##take the R squared to convert 70 | R2 = .06 71 | feta = R2 / (1-R2) 72 | 73 | #u is df model, which is number of predictors 74 | #v is df error, but we are trying to figure out 75 | #sample size so we leave this one blank. 76 | #f2 is cohen f squared 77 | 78 | pwr.f2.test(u = 4, v = NULL, f2 = feta, sig.level = .05, power = .80) 79 | #remember that you need to add u + v to get final sample size -------------------------------------------------------------------------------- /examples/example_mediation2.R: -------------------------------------------------------------------------------- 1 | ##An example of mediation 2 2 | #download the data from our github examples page 3 | master = read.csv("mediation2.csv") 4 | 5 | ##install if you need to 6 | devtools::install_github("doomlab/MeMoBootR") 7 | 8 | ##load the library 9 | library(MeMoBootR) 10 | 11 | saved = mediation2(y = "Q11", #DV 12 | x = "Q151", #IV 13 | m1 = "Q31", #Mediator 1 14 | m2 = "Q41", #Mediator 2 15 | cvs = c("Q121"), #Any covariates 16 | df = master, #Dataframe 17 | with_out = F, #Not required but can change to F for no outliers 18 | nboot = 1000, #Number of bootstraps 19 | conf_level = .95 #CI width 20 | ) 21 | 22 | ####view data screening#### 23 | #outlier information is in the DF 24 | View(saved$datascreening$fulldata) 25 | sum(saved$datascreening$fulldata$totalout >=2) 26 | 27 | #additivity 28 | saved$datascreening$correl 29 | 30 | #linearity 31 | saved$datascreening$linearity 32 | 33 | #normality 34 | saved$datascreening$normality 35 | 36 | #homogs 37 | saved$datascreening$homogen 38 | 39 | ####view the analysis#### 40 | summary(saved$model1) #c path 41 | 42 | #overall grade predicts overall course b = 0.41, t(3588) = 17.69, p < .001 43 | #wanted to take predicts overall course b = 0.37, t(3588) = 31.50, p < .001 44 | 45 | summary(saved$model2) #a1 path 46 | 47 | #a1 path is x predicting m1 48 | #overall grade predicts exam fairness b = 0.45, t(3588) = 23.26, p < .001 49 | 50 | summary(saved$model3) #a2 d21 paths 51 | 52 | #a2 path is x predicting m2 53 | #overall grade predicts grading fairness b = 0.11, t(3587) = 8.77, p < .001 54 | #d21 path is m1 predicting m2 55 | #exam fairness predicts grading fairness b = 0.56, t(3587) = 14.34, p < .001 56 | 57 | summary(saved$model4) #b1, b2, c' paths 58 | 59 | #b1 m1 predicting y 60 | #exam fairness predicts overall course rating b = 0.58, t(3586) = 30.12, p < .001 61 | #b2 m2 predicting y 62 | #overall grading fairness predicts overall course rating 63 | #b = 0.41, t(3586) = 18.01, p < .001 64 | #c' path x predicting y 65 | #overall grade does not predict overall course b < 0.01, t(3586) = 0.07, p = .944 66 | 67 | #total, direct, indirect effects 68 | saved$total.effect 69 | saved$direct.effect 70 | saved$indirect.effect1 #x through m1 71 | saved$indirect.effect2 #x through m2 72 | saved$indirect.effect3 #x through m1 through m2 73 | 74 | #bootstrapped indirect 75 | saved$boot.results 76 | 77 | #bootstrapped CI 78 | saved$boot.ci 79 | #or 80 | saved$boot.ci$Q151.1 81 | 82 | #indirect effect of exam fairness between overall grading and overall course 83 | #indirect = 0.26, SE = 0.02, 95% CI[0.22, 0.29] 84 | 85 | saved$boot.ci$Q151.2 #repeat above process to write out 86 | saved$boot.ci$Q151.3 87 | 88 | ##how do i know if mediation occurs ? if the CI does NOT include zero 89 | #all three indirects show mediation effects 90 | 91 | ####power#### 92 | library(pwr) 93 | ##power runs on cohen's f - not to be confused with anova f. 94 | ##take the R squared to convert 95 | R2 = .60 96 | feta = R2 / (1-R2) 97 | 98 | #u is df model, which is number of predictors 99 | #v is df error, but we are trying to figure out 100 | #sample size so we leave this one blank. 101 | #f2 is cohen f squared 102 | 103 | pwr.f2.test(u = 4, v = NULL, f2 = feta, sig.level = .05, power = .80) 104 | #remember that you need to add u + v to get final sample size 105 | -------------------------------------------------------------------------------- /examples/example_mediation2_moda.R: -------------------------------------------------------------------------------- 1 | # Serial Mediation with Moderation on A1 Path 2 | 3 | # Install package 4 | library(devtools) 5 | install_github("doomlab/MeMoBootR") 6 | 7 | # Toy data 8 | set.seed(123) 9 | N <- 200 10 | X <- rep(c("C", "T"), each = 100) # c = control vs. t = treatment 11 | M1 <- c(rnorm(100, 1.17, .2), rnorm(100, 2.99, .2)) 12 | M2 <- 1.2*M1 + rnorm(N, 2.5, .2) 13 | Y <- 0.2*M2 + rnorm(N, 2.5, .2) 14 | W <- 0.7*M1 + rnorm(N, 2.5, .2) 15 | data1 <- data.frame(X, M1, M2, W, Y) 16 | 17 | # Demo of new MeMoBootR function 18 | library(MeMoBootR) 19 | 20 | saved <- mediation2_moda(y = "Y", 21 | x = "X", 22 | m1 = "M1", 23 | m2 = "M2", 24 | mod = "W", 25 | cvs = NULL, 26 | df = data1, 27 | with_out = T, 28 | nboot = 1000, 29 | conf_level = .95) 30 | 31 | ####view data screening#### 32 | #outlier information is in the DF 33 | View(saved$datascreening$fulldata) 34 | sum(saved$datascreening$fulldata$totalout >=2) 35 | 36 | #additivity 37 | saved$datascreening$correl 38 | 39 | #linearity 40 | saved$datascreening$linearity 41 | 42 | #normality 43 | saved$datascreening$normality 44 | 45 | #homogs 46 | saved$datascreening$homogen 47 | 48 | ####view the analysis#### 49 | ## note that all X, M1, M2, W are centered 50 | ## unless they are categorical 51 | 52 | summary(saved$model1) #c path 53 | 54 | summary(saved$model2) #a1_avg path 55 | summary(saved$model2_low) #a1_low path 56 | summary(saved$model2_high) #a2_high path 57 | 58 | summary(saved$model3) #a2 d21 paths 59 | 60 | summary(saved$model4) #b1, b2, c' paths 61 | 62 | #total, direct, indirect effects 63 | saved$total.effect 64 | saved$direct.effect 65 | saved$indirect.effect1_avg #x through m1 when w is avg 66 | saved$indirect.effect1_low #x through m2 when w is low 67 | saved$indirect.effect1_high #x through m2 when w is high 68 | saved$indirect.effect2 #x through m2 69 | saved$indirect.effect3_avg #x through m1 through m2 when w is avg 70 | saved$indirect.effect3_low #x through m1 through m2 when w is low 71 | saved$indirect.effect3_high #x through m1 through m2 when w is high 72 | 73 | #bootstrapped indirect 74 | saved$boot.results 75 | 76 | #bootstrapped CI 77 | saved$boot.ci 78 | #OR 79 | saved$boot.ci$XT.indirect1_avg #x through m1 80 | saved$boot.ci$XT.indirect1_low 81 | saved$boot.ci$XT.indirect1_high 82 | saved$boot.ci$XT.indirect2 #x through m2 83 | saved$boot.ci$XT.indirect3_avg #x through m1 and m2 84 | saved$boot.ci$XT.indirect3_low 85 | saved$boot.ci$XT.indirect3_high 86 | 87 | ##how do i know if mediation occurs ? if the CI does NOT include zero 88 | 89 | ####power#### 90 | library(pwr) 91 | ##power runs on cohen's f - not to be confused with anova f. 92 | ##take the R squared to convert 93 | R2 = .52 94 | feta = R2 / (1-R2) 95 | 96 | #u is df model, which is number of predictors 97 | #v is df error, but we are trying to figure out 98 | #sample size so we leave this one blank. 99 | #f2 is cohen f squared 100 | 101 | pwr.f2.test(u = 4, v = NULL, f2 = feta, sig.level = .05, power = .80) 102 | #remember that you need to add u + v to get final sample size 103 | 104 | 105 | -------------------------------------------------------------------------------- /examples/example_moderation1 cat.R: -------------------------------------------------------------------------------- 1 | #An example of two way moderation with categorical M 2 | 3 | ##install if you need to 4 | devtools::install_github("doomlab/MeMoBootR") 5 | 6 | ##load the library 7 | library(MeMoBootR) 8 | 9 | #load the dataset from R 10 | states = as.data.frame(state.x77) 11 | 12 | #create fake categorical variable 13 | states$Murder_cat = states$Murder 14 | states$Murder_cat = as.factor(ifelse(states$Murder < 5, "Low", 15 | ifelse(states$Murder < 9, "Average", "High"))) 16 | states$Murder_cat = factor(states$Murder_cat, 17 | levels = c("Low", "Average", "High")) 18 | 19 | saved = moderation1(y = "Income", #DV 20 | x = "Illiteracy", #IV 21 | m = "Murder_cat", #Moderator for simple slopes 22 | cvs = NULL, #covariates 23 | df = states, #data frame of columns 24 | with_out = T) 25 | 26 | #View the outliers 27 | View(saved$datascreening$fulldata) 28 | 29 | #Additivity/multicollinearity 30 | saved$datascreening$correl 31 | 32 | #Linearity 33 | saved$datascreening$linearity 34 | 35 | #Normality 36 | saved$datascreening$normality 37 | 38 | #Homogeneity + Homoscedasticity 39 | saved$datascreening$homogen 40 | 41 | #Overall Model (Average Simple Slopes) 42 | summary(saved$model1) 43 | 44 | ##overall model statistics 45 | #F(5,44) = 5.23, p = .001, R2 = .37 46 | 47 | ##each predictor one at a time 48 | #Illiteracy b = 622.70, t(44) = 1.09, p = .280 49 | #illiteracy does not predict income rates 50 | 51 | #Murder Average versus low b = -291.80, t(44) = -0.92, p = .363 52 | #not a significant difference between low and average murder rates for income 53 | #Murder High versus low b = -122.80, ... not significant 54 | tapply(states$Income, states$Murder_cat, mean) 55 | 56 | ##Interaction 57 | #Illiteracy by average versus low not significant 58 | #Illiteracy by high versus low is significant 59 | 60 | #break down by M 61 | #illiteracy predicting income for each group/level of murder 62 | 63 | #Simple slopes by levels of M 64 | saved$slopemodels 65 | 66 | ##view with lapply 67 | lapply(saved$slopemodels, summary) 68 | 69 | #Low murder levels, illiteracy b = 622.70 not significant 70 | #Average b = 125.00 not significant 71 | #High b = -902.60 is significant 72 | 73 | #at low and average murder rates, illiteracy does not predict income 74 | #at high murder rates, illiteracy negatively predicts income 75 | 76 | ##or pull one at a time 77 | summary(saved$slopemodels$Low) 78 | coef(saved$slopemodels$Low) 79 | 80 | summary(saved$slopemodels$Average) 81 | 82 | #Interpretation of Slopes 83 | cat(saved$interpretation) 84 | 85 | #Graph of the Slopes 86 | saved$graphslopes 87 | 88 | #remember, you can run the function with out () 89 | #to view the graph code if you want to tweak it more 90 | moderation1 91 | 92 | ####Power#### 93 | library(pwr) 94 | ##power runs on cohen's f - not to be confused with anova f. 95 | ##take the R squared to convert 96 | R2 = .20 97 | feta = R2 / (1-R2) 98 | 99 | #u is df model, which is number of predictors 100 | #v is df error, but we are trying to figure out 101 | #sample size so we leave this one blank. 102 | #f2 is cohen f squared 103 | 104 | ##all the predictors 105 | pwr.f2.test(u = 5, v = NULL, f2 = feta, sig.level = .05, power = .80) 106 | #remember that you need to add u + v to get final sample size 107 | 108 | ##addition of the interaction only 109 | pwr.f2.test(u = 2, v = NULL, f2 = feta, sig.level = .05, power = .80) 110 | #remember that you need to add u + v to get final sample size 111 | -------------------------------------------------------------------------------- /examples/example_moderation1.R: -------------------------------------------------------------------------------- 1 | #An example of two way moderation with covariates 2 | 3 | ##install if you need to 4 | devtools::install_github("doomlab/MeMoBootR") 5 | 6 | ##load the library 7 | library(MeMoBootR) 8 | 9 | #load the dataset from R 10 | states = as.data.frame(state.x77) 11 | 12 | saved = moderation1(y = "Income", #DV 13 | x = "Illiteracy", #IV 14 | m = "Murder", #Moderator for simple slopes 15 | cvs = c("Population", "Area"), #covariates 16 | df = states, #data frame of columns 17 | with_out = T) 18 | 19 | #View the outliers 20 | View(saved$datascreening$fulldata) 21 | 22 | #Additivity/multicollinearity 23 | saved$datascreening$correl 24 | 25 | #Linearity 26 | saved$datascreening$linearity 27 | 28 | #Normality 29 | saved$datascreening$normality 30 | 31 | #Homogeneity + Homoscedasticity 32 | saved$datascreening$homogen 33 | 34 | #Overall Model (Average Simple Slopes) 35 | summary(saved$model1) 36 | 37 | ##overall model statistics 38 | #F(5, 44) = 10.30, p < .001, R2 = .54 39 | 40 | ##each predictor one at a time 41 | #Illiteracy b = -114.78, t(44) = -0.67, p = .508, not significant predictor 42 | #Murder, also not signifificant 43 | #Population, as population increases, income increases 44 | #Area, as area increases, income increases 45 | #Interaction b = -115.56, t(44) = -3.36, p = .002 - significant 46 | #difficult to interpret... 47 | 48 | #Low Simple Slope Model 49 | summary(saved$model1low) 50 | 51 | #look for is X because M is the slope we are manipulating 52 | #Illiteracy not predictor of Income 53 | 54 | #High Simple Slope Model 55 | summary(saved$model1high) 56 | 57 | #Illiteracy is predictor of income 58 | 59 | #Interpretation of Slopes 60 | cat(saved$interpretation) 61 | 62 | ##what does it mean if the interaction is significant but none of the simple 63 | ##slopes are significant...?? 64 | ###implies the simple slopes are changing/different but that the main effect 65 | ###X to Y is not significant 66 | 67 | #Graph of the Slopes 68 | saved$graphslopes 69 | 70 | #remember, you can run the function with out () 71 | #to view the graph code if you want to tweak it more 72 | moderation1 73 | 74 | ####Power#### 75 | library(pwr) 76 | ##power runs on cohen's f - not to be confused with anova f. 77 | ##take the R squared to convert 78 | R2 = .11 79 | feta = R2 / (1-R2) 80 | 81 | #u is df model, which is number of predictors 82 | #v is df error, but we are trying to figure out 83 | #sample size so we leave this one blank. 84 | #f2 is cohen f squared 85 | 86 | ##all the predictors 87 | pwr.f2.test(u = 5, v = NULL, f2 = feta, sig.level = .05, power = .80) 88 | #remember that you need to add u + v to get final sample size 89 | 90 | ##addition of the interaction only 91 | pwr.f2.test(u = 1, v = NULL, f2 = feta, sig.level = .05, power = .80) 92 | #remember that you need to add u + v to get final sample size 93 | -------------------------------------------------------------------------------- /examples/example_moderation2.R: -------------------------------------------------------------------------------- 1 | #An example of double two way moderation with covariates 2 | #download the data from our github examples page 3 | master = read.csv("mediation2.csv") 4 | 5 | ##install if you need to 6 | devtools::install_github("doomlab/MeMoBootR") 7 | 8 | ##load the library 9 | library(MeMoBootR) 10 | 11 | saved = moderation2(y = "Q11", #DV 12 | x = "Q151", #IV 13 | m1 = "Q31", #Moderator 1 14 | m2 = "Q41", #Moderator 2 15 | cvs = c("Q121"), #Any covariates 16 | df = master, #Dataframe 17 | with_out = F #include outliers or not 18 | ) 19 | 20 | #View the outliers 21 | View(saved$datascreening$fulldata) 22 | sum(saved$datascreening$fulldata$totalout >= 2) 23 | 24 | #Additivity/multicollinearity 25 | saved$datascreening$correl 26 | 27 | #Linearity 28 | saved$datascreening$linearity 29 | 30 | #Normality 31 | saved$datascreening$normality 32 | 33 | #Homogeneity + Homoscedasticity 34 | saved$datascreening$homogen 35 | 36 | #Overall Model - Average M1, Average M2 37 | summary(saved$avgm1_avgm2) 38 | 39 | #this model is the overall model that you would run 40 | #to determine if you even wanted to do simple slopes 41 | #main effect 42 | #course grade doesn't predict overall eval 43 | #b = .004, t(3570) = 0.25, p = .805 44 | #exam fairness does predict overall eval 45 | #grade fairness does predict overall eval 46 | 47 | #covariate adjustor 48 | #course wanted to take predicts overall eval 49 | 50 | #interaction course grade and exam b = -0.10, t(3570) = -1.84, p = .066 51 | #interaction course grade and grade fairness is significant 52 | 53 | #overall model 54 | #F(6,3570) = 1148, p < .001, R2 = .659 all six predictors are significant 55 | 56 | #there are eight more models with the combinations 57 | #of m1 and m2 at low, average, high 58 | summary(saved$avgm1_lowm2) 59 | summary(saved$avgm1_highm2) 60 | 61 | #you can view each one for reporting or look at X for each 62 | View(saved$interpretation) 63 | #each number is x predicting y at the "area" of the data 64 | 65 | #Graph of the Slopes by M1 66 | saved$lowm1_graph 67 | saved$avgm1_graph 68 | saved$highm1_graph 69 | 70 | ####Power#### 71 | library(pwr) 72 | ##power runs on cohen's f - not to be confused with anova f. 73 | ##take the R squared to convert 74 | R2 = .03 75 | feta = R2 / (1-R2) 76 | 77 | #u is df model, which is number of predictors 78 | #v is df error, but we are trying to figure out 79 | #sample size so we leave this one blank. 80 | #f2 is cohen f squared 81 | 82 | ##all the predictors 83 | #x, m1, m2, cv1, x*m1, x*m2 = 6 84 | pwr.f2.test(u = 6, v = NULL, f2 = feta, sig.level = .05, power = .80) 85 | #remember that you need to add u + v to get final sample size 86 | 87 | ##addition of the interaction only 88 | #x*m1 + x*m2 89 | pwr.f2.test(u = 2, v = NULL, f2 = feta, sig.level = .05, power = .80) 90 | #remember that you need to add u + v to get final sample size 91 | -------------------------------------------------------------------------------- /examples/mediation1 cat.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/mediation1 cat.docx -------------------------------------------------------------------------------- /examples/mediation1.csv: -------------------------------------------------------------------------------- 1 | "mpg","cyl","disp","hp","drat","wt","qsec","vs","am","gear","carb" 2 | 21,6,160,110,3.9,2.62,16.46,0,1,4,4 3 | 21,6,160,110,3.9,2.875,17.02,0,1,4,4 4 | 22.8,4,108,93,3.85,2.32,18.61,1,1,4,1 5 | 21.4,6,258,110,3.08,3.215,19.44,1,0,3,1 6 | 18.7,8,360,175,3.15,3.44,17.02,0,0,3,2 7 | 18.1,6,225,105,2.76,3.46,20.22,1,0,3,1 8 | 14.3,8,360,245,3.21,3.57,15.84,0,0,3,4 9 | 24.4,4,146.7,62,3.69,3.19,20,1,0,4,2 10 | 22.8,4,140.8,95,3.92,3.15,22.9,1,0,4,2 11 | 19.2,6,167.6,123,3.92,3.44,18.3,1,0,4,4 12 | 17.8,6,167.6,123,3.92,3.44,18.9,1,0,4,4 13 | 16.4,8,275.8,180,3.07,4.07,17.4,0,0,3,3 14 | 17.3,8,275.8,180,3.07,3.73,17.6,0,0,3,3 15 | 15.2,8,275.8,180,3.07,3.78,18,0,0,3,3 16 | 10.4,8,472,205,2.93,5.25,17.98,0,0,3,4 17 | 10.4,8,460,215,3,5.424,17.82,0,0,3,4 18 | 14.7,8,440,230,3.23,5.345,17.42,0,0,3,4 19 | 32.4,4,78.7,66,4.08,2.2,19.47,1,1,4,1 20 | 30.4,4,75.7,52,4.93,1.615,18.52,1,1,4,2 21 | 33.9,4,71.1,65,4.22,1.835,19.9,1,1,4,1 22 | 21.5,4,120.1,97,3.7,2.465,20.01,1,0,3,1 23 | 15.5,8,318,150,2.76,3.52,16.87,0,0,3,2 24 | 15.2,8,304,150,3.15,3.435,17.3,0,0,3,2 25 | 13.3,8,350,245,3.73,3.84,15.41,0,0,3,4 26 | 19.2,8,400,175,3.08,3.845,17.05,0,0,3,2 27 | 27.3,4,79,66,4.08,1.935,18.9,1,1,4,1 28 | 26,4,120.3,91,4.43,2.14,16.7,0,1,5,2 29 | 30.4,4,95.1,113,3.77,1.513,16.9,1,1,5,2 30 | 15.8,8,351,264,4.22,3.17,14.5,0,1,5,4 31 | 19.7,6,145,175,3.62,2.77,15.5,0,1,5,6 32 | 15,8,301,335,3.54,3.57,14.6,0,1,5,8 33 | 21.4,4,121,109,4.11,2.78,18.6,1,1,4,2 34 | -------------------------------------------------------------------------------- /examples/mediation1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/mediation1.docx -------------------------------------------------------------------------------- /examples/mediation1.sav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/mediation1.sav -------------------------------------------------------------------------------- /examples/mediation2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/mediation2.docx -------------------------------------------------------------------------------- /examples/mediation2.sav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/mediation2.sav -------------------------------------------------------------------------------- /examples/moderation1 cat.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/moderation1 cat.docx -------------------------------------------------------------------------------- /examples/moderation1.csv: -------------------------------------------------------------------------------- 1 | "Population","Income","Illiteracy","Life Exp","Murder","HS Grad","Frost","Area" 2 | 3615,3624,2.1,69.05,15.1,41.3,20,50708 3 | 365,6315,1.5,69.31,11.3,66.7,152,566432 4 | 2212,4530,1.8,70.55,7.8,58.1,15,113417 5 | 2110,3378,1.9,70.66,10.1,39.9,65,51945 6 | 21198,5114,1.1,71.71,10.3,62.6,20,156361 7 | 2541,4884,0.7,72.06,6.8,63.9,166,103766 8 | 3100,5348,1.1,72.48,3.1,56,139,4862 9 | 579,4809,0.9,70.06,6.2,54.6,103,1982 10 | 8277,4815,1.3,70.66,10.7,52.6,11,54090 11 | 4931,4091,2,68.54,13.9,40.6,60,58073 12 | 868,4963,1.9,73.6,6.2,61.9,0,6425 13 | 813,4119,0.6,71.87,5.3,59.5,126,82677 14 | 11197,5107,0.9,70.14,10.3,52.6,127,55748 15 | 5313,4458,0.7,70.88,7.1,52.9,122,36097 16 | 2861,4628,0.5,72.56,2.3,59,140,55941 17 | 2280,4669,0.6,72.58,4.5,59.9,114,81787 18 | 3387,3712,1.6,70.1,10.6,38.5,95,39650 19 | 3806,3545,2.8,68.76,13.2,42.2,12,44930 20 | 1058,3694,0.7,70.39,2.7,54.7,161,30920 21 | 4122,5299,0.9,70.22,8.5,52.3,101,9891 22 | 5814,4755,1.1,71.83,3.3,58.5,103,7826 23 | 9111,4751,0.9,70.63,11.1,52.8,125,56817 24 | 3921,4675,0.6,72.96,2.3,57.6,160,79289 25 | 2341,3098,2.4,68.09,12.5,41,50,47296 26 | 4767,4254,0.8,70.69,9.3,48.8,108,68995 27 | 746,4347,0.6,70.56,5,59.2,155,145587 28 | 1544,4508,0.6,72.6,2.9,59.3,139,76483 29 | 590,5149,0.5,69.03,11.5,65.2,188,109889 30 | 812,4281,0.7,71.23,3.3,57.6,174,9027 31 | 7333,5237,1.1,70.93,5.2,52.5,115,7521 32 | 1144,3601,2.2,70.32,9.7,55.2,120,121412 33 | 18076,4903,1.4,70.55,10.9,52.7,82,47831 34 | 5441,3875,1.8,69.21,11.1,38.5,80,48798 35 | 637,5087,0.8,72.78,1.4,50.3,186,69273 36 | 10735,4561,0.8,70.82,7.4,53.2,124,40975 37 | 2715,3983,1.1,71.42,6.4,51.6,82,68782 38 | 2284,4660,0.6,72.13,4.2,60,44,96184 39 | 11860,4449,1,70.43,6.1,50.2,126,44966 40 | 931,4558,1.3,71.9,2.4,46.4,127,1049 41 | 2816,3635,2.3,67.96,11.6,37.8,65,30225 42 | 681,4167,0.5,72.08,1.7,53.3,172,75955 43 | 4173,3821,1.7,70.11,11,41.8,70,41328 44 | 12237,4188,2.2,70.9,12.2,47.4,35,262134 45 | 1203,4022,0.6,72.9,4.5,67.3,137,82096 46 | 472,3907,0.6,71.64,5.5,57.1,168,9267 47 | 4981,4701,1.4,70.08,9.5,47.8,85,39780 48 | 3559,4864,0.6,71.72,4.3,63.5,32,66570 49 | 1799,3617,1.4,69.48,6.7,41.6,100,24070 50 | 4589,4468,0.7,72.48,3,54.5,149,54464 51 | 376,4566,0.6,70.29,6.9,62.9,173,97203 52 | -------------------------------------------------------------------------------- /examples/moderation1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/moderation1.docx -------------------------------------------------------------------------------- /examples/moderation1.sav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/moderation1.sav -------------------------------------------------------------------------------- /examples/moderation2.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/examples/moderation2.docx -------------------------------------------------------------------------------- /man/createformula.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/createformula.R 3 | \name{createformula} 4 | \alias{createformula} 5 | \title{Create Regression Formulas} 6 | \usage{ 7 | createformula(y, x, m, m2 = NULL, mod = NULL, cvs = NULL, type) 8 | } 9 | \arguments{ 10 | \item{y}{The dependent variable column name from your dataframe.} 11 | 12 | \item{x}{The independent variable column name from your dataframe. This column will be treated as X in mediation or moderation models, please see diagrams online for examples.} 13 | 14 | \item{m}{The first mediator or moderator for your model.} 15 | 16 | \item{m2}{The second mediator or moderator for your model.} 17 | 18 | \item{mod}{A moderator for a moderated mediation model.} 19 | 20 | \item{cvs}{The covariates you would like to include in the model. Use a `c()` concatenated vector to use multiple covariates.} 21 | } 22 | \description{ 23 | This function creates the formulas for \code{lm()} to run the 24 | regression models necessary for data screening and mediation 25 | or moderation models. 26 | } 27 | \details{ 28 | The output currently includes a list of equations used for simple mediation, 29 | which will updated as moderation is added to the package. 30 | } 31 | \examples{ 32 | createformula(y = "cyl", x = "mpg", m = "disp", 33 | cvs = c("drat", "gear"), type = "moderation1") 34 | } 35 | \keyword{formulas} 36 | \keyword{mediation,} 37 | \keyword{moderation,} 38 | \keyword{regression,} 39 | -------------------------------------------------------------------------------- /man/datascreen.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datascreen.R 3 | \name{datascreen} 4 | \alias{datascreen} 5 | \title{Data Screening for Regression} 6 | \usage{ 7 | datascreen(eq, df, with_out = T) 8 | } 9 | \arguments{ 10 | \item{eq}{The full equation with all x, m, and cvs created from the 11 | \code{createformula()} function.} 12 | 13 | \item{df}{The dataframe where the columns from the formula can 14 | be found. Note that only the columns used in the analysis will be screened.} 15 | 16 | \item{with_out}{A logical value where you want to keep the outliers in 17 | the data screening \code{TRUE} or exclude them from the data screening \code{FALSE}.} 18 | } 19 | \description{ 20 | This function using the data screening procedures outlined 21 | by Tabachnick and Fidell (2012) to analyze the data for outliers 22 | using Mahalanobis distance, Cook's, and Leverage values. 23 | Further, the output includes correlations for additivity/multicollinearity, 24 | and plots for linearity, normality, and homogeneity/homoscedasticity. 25 | You can learn more about the data screening procedure implemented here at 26 | the Statistics of DOOM YouTube channel. 27 | } 28 | \examples{ 29 | datascreen(eq = "mpg ~ cyl + disp + drat + gear", 30 | df = mtcars, with_out = TRUE) 31 | } 32 | \keyword{data} 33 | \keyword{mediation,} 34 | \keyword{moderation,} 35 | \keyword{regression,} 36 | \keyword{screening} 37 | -------------------------------------------------------------------------------- /man/draw.med.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/draw.med.R 3 | \name{draw.med} 4 | \alias{draw.med} 5 | \title{Simple Mediation Diagrams} 6 | \usage{ 7 | draw.med(model1, model2, model3, y, x, m, df) 8 | } 9 | \arguments{ 10 | \item{model1}{The saved regression model of \code{y~x} model where X predicts Y.} 11 | 12 | \item{model2}{The saved regression model of \code{m~x} model where X predicts M.} 13 | 14 | \item{model3}{The saved regression model of \code{y~x+m} model where X and M predict Y.} 15 | 16 | \item{y}{The dependent variable from your mediation.} 17 | 18 | \item{x}{The x variable from your mediation.} 19 | 20 | \item{m}{The mediator from your mediation.} 21 | 22 | \item{df}{The dataframe containing the y, x, m columns.} 23 | } 24 | \description{ 25 | This function returns the code to create a simple mediation triangle, 26 | as well as the basic diagram using the \code{diagram} library. 27 | } 28 | \examples{ 29 | draw.med(saved$model1, saved$model2, saved$model3) 30 | Note in this example saved is the name of the model saved from mediation1. 31 | You can include any form of model names that you have saved from \\code{lm()}. 32 | You can also type \\code{draw.med} in your console to get this code and edit 33 | the diagram parameters to your liking. 34 | } 35 | \keyword{bootstrapping,} 36 | \keyword{data} 37 | \keyword{diagram} 38 | \keyword{mediation,} 39 | \keyword{screening,} 40 | -------------------------------------------------------------------------------- /man/indirectmed.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/indirectmed.R 3 | \name{indirectmed} 4 | \alias{indirectmed} 5 | \title{Indirect Effect for Mediation} 6 | \usage{ 7 | indirectmed(formula2, formula3, x, med.var, df, random) 8 | } 9 | \arguments{ 10 | \item{formula2}{The formula for mediation for the a path, usually 11 | \code{m ~ x}. Can also include covariates and will be \code{eq2} 12 | if the \code{createformula()} function is used.} 13 | 14 | \item{formula3}{The formula for mediation for the b path, usually 15 | \code{y ~ x + m}. Can also include covariates and will be 16 | \code{eq3} if the \code{createformula()} function is used.} 17 | 18 | \item{x}{The column name for x in the data frame.} 19 | 20 | \item{med.var}{The column name for m in the data frame.} 21 | 22 | \item{df}{The dataframe where the columns from the formula can be found.} 23 | 24 | \item{random}{This variable is used to denote the data frame will be 25 | randomize by row, as part of the \code{boot} library.} 26 | } 27 | \description{ 28 | This function runs a simple mediation model to calculate 29 | the indirect effect, which will be used for bootstrapping 30 | the confidence interval of the indirect effect. This function 31 | is used in conjunction with the \code{boot} function and is formatted to 32 | work as a bootstrapped effect. 33 | } 34 | \examples{ 35 | indirectmed("disp ~ mpg", "cyl ~ mpg + disp", mtcars) 36 | } 37 | \keyword{effect} 38 | \keyword{indirect} 39 | \keyword{mediation,} 40 | \keyword{regression,} 41 | -------------------------------------------------------------------------------- /man/indirectmed2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/indirectmed2.R 3 | \name{indirectmed2} 4 | \alias{indirectmed2} 5 | \title{Indirect Effect for Serial Mediation} 6 | \usage{ 7 | indirectmed2(formula2, formula3, formula4, x, m1, m2, df, random) 8 | } 9 | \arguments{ 10 | \item{formula2}{The formula for mediation for the a1 path, usually 11 | \code{m1 ~ x}. Can also include covariates and will be \code{eq2} 12 | if the \code{createformula()} function is used.} 13 | 14 | \item{formula3}{The formula for mediation for the a2 and d21 paths, usually 15 | \code{m2 ~ x + m1}. Can also include covariates and will be 16 | \code{eq3} if the \code{createformula()} function is used.} 17 | 18 | \item{formula4}{The formula for mediation for the b1 and b2 paths, usually 19 | \code{y ~ x + m1 + m2}. Can also include covariates and will be \code{eq4} if the 20 | \code{createformula()} function is used.} 21 | 22 | \item{x}{The column name for x in the data frame.} 23 | 24 | \item{m1}{The column name for mediator 1 in the data frame.} 25 | 26 | \item{m2}{The column name for mediator 2 in the data frame.} 27 | 28 | \item{random}{This variable is used to denote the data frame will be 29 | randomize by row, as part of the \code{boot} library.} 30 | 31 | \item{data}{The dataframe where the columns from the formula can be found.} 32 | } 33 | \description{ 34 | This function runs a serial mediation model with two mediators to calculate 35 | the indirect effect, which will be used for bootstrapping 36 | the confidence interval of the indirect effect. This function 37 | is used in conjunction with the \code{boot} function and is formatted to 38 | work as a bootstrapped effect. 39 | } 40 | \examples{ 41 | indirectmed2("Q31 ~ Q151", "Q41 ~ Q151 + Q31", 42 | "Q11 ~ Q151 + Q31 + Q41", mtcars) 43 | } 44 | \keyword{effect} 45 | \keyword{indirect} 46 | \keyword{mediation,} 47 | \keyword{regression,} 48 | -------------------------------------------------------------------------------- /man/indirectmed2_moda.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/indirectmed2_moda.R 3 | \name{indirectmed2_moda} 4 | \alias{indirectmed2_moda} 5 | \title{Indirect Effect for Serial Mediation and Moderator on Path A} 6 | \usage{ 7 | indirectmed2_moda(formula2, formula3, formula4, x, m1, m2, mod, df, random) 8 | } 9 | \arguments{ 10 | \item{formula2}{The formula for mediation for the a1 path, usually 11 | \code{m1 ~ x}. Can also include covariates and will be \code{eq2} 12 | if the \code{createformula()} function is used. This effect will 13 | also have a moderator for this model.} 14 | 15 | \item{formula3}{The formula for mediation for the a2 and d21 paths, usually 16 | \code{m2 ~ x + m1}. Can also include covariates and will be 17 | \code{eq3} if the \code{createformula()} function is used.} 18 | 19 | \item{formula4}{The formula for mediation for the b1 and b2 paths, usually 20 | \code{y ~ x + m1 + m2}. Can also include covariates and will be \code{eq4} if the 21 | \code{createformula()} function is used.} 22 | 23 | \item{x}{The column name for x in the data frame.} 24 | 25 | \item{m1}{The column name for mediator 1 in the data frame.} 26 | 27 | \item{m2}{The column name for mediator 2 in the data frame.} 28 | 29 | \item{mod}{The column name for the moderator in the data frame.} 30 | 31 | \item{random}{This variable is used to denote the data frame will be 32 | randomize by row, as part of the \code{boot} library.} 33 | 34 | \item{data}{The dataframe where the columns from the formula can be found.} 35 | } 36 | \description{ 37 | This function runs a serial mediation model with two mediators to calculate 38 | the indirect effect, which will be used for bootstrapping 39 | the confidence interval of the indirect effect. This function 40 | is used in conjunction with the \code{boot} function and is formatted to 41 | work as a bootstrapped effect. This mediation model includes a 42 | moderator on path A1. 43 | } 44 | \examples{ 45 | indirectmed2("Q31 ~ Q151*Q121", "Q41 ~ Q151 + Q31", 46 | "Q11 ~ Q151 + Q31 + Q41", mtcars) 47 | } 48 | \keyword{effect} 49 | \keyword{indirect} 50 | \keyword{mediation,} 51 | \keyword{regression,} 52 | -------------------------------------------------------------------------------- /man/mediation1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mediation1.R 3 | \name{mediation1} 4 | \alias{mediation1} 5 | \title{Simple Mediation} 6 | \usage{ 7 | mediation1( 8 | y, 9 | x, 10 | m, 11 | cvs = NULL, 12 | df, 13 | with_out = T, 14 | nboot = 1000, 15 | conf_level = 0.95 16 | ) 17 | } 18 | \arguments{ 19 | \item{y}{The dependent variable column name from your dataframe.} 20 | 21 | \item{x}{The independent variable column name from your dataframe. This column 22 | will be treated as X in mediation or moderation models, please see 23 | diagrams online for examples.} 24 | 25 | \item{m}{The mediator for your model, as this model only includes one mediator.} 26 | 27 | \item{cvs}{The covariates you would like to include in the model. 28 | Use a \code{c()} concatenated vector to use multiple covariates.} 29 | 30 | \item{df}{The dataframe where the columns from the formula can be found. 31 | Note that only the columns used in the analysis will be data screened.} 32 | 33 | \item{with_out}{A logical value where you want to keep the outliers in 34 | model \code{TRUE} or exclude them from the model \code{FALSE}.} 35 | 36 | \item{nboot}{A numeric value indicating the number of bootstraps you would like to complete.} 37 | 38 | \item{conf_level}{A numeric value indicating the confidence interval width for the boostrapped confidence interval.} 39 | } 40 | \description{ 41 | This function runs a complete simple mediation analysis with one 42 | mediator, similiar to model 4 in PROCESS by A. Hayes (2013). 43 | As part of the output, you will find data screening, 44 | all three models used in the traditional Baron and 45 | Kenny (1986) steps, total/direct/indirect effects, the z-score and p-value 46 | for the Aroian Sobel test, and the bootstrapped confidence interval 47 | for the indirect effect. 48 | } 49 | \examples{ 50 | mediation1(y = "cyl", x = "mpg", m = "disp", 51 | cvs = c("drat", "gear"), df = mtcars) 52 | } 53 | \keyword{bootstrapping} 54 | \keyword{data} 55 | \keyword{mediation,} 56 | \keyword{moderation,} 57 | \keyword{regression,} 58 | \keyword{screening,} 59 | -------------------------------------------------------------------------------- /man/mediation2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mediation2.R 3 | \name{mediation2} 4 | \alias{mediation2} 5 | \title{Serial Mediation with Two Mediators} 6 | \usage{ 7 | mediation2( 8 | y, 9 | x, 10 | m1, 11 | m2, 12 | cvs = NULL, 13 | df, 14 | with_out = T, 15 | nboot = 1000, 16 | conf_level = 0.95 17 | ) 18 | } 19 | \arguments{ 20 | \item{y}{The dependent variable column name from your dataframe.} 21 | 22 | \item{x}{The independent variable column name from your dataframe. This column 23 | will be treated as X in mediation or moderation models, please see 24 | diagrams online for examples.} 25 | 26 | \item{m1}{The first mediator for your model.} 27 | 28 | \item{m2}{The second mediator for your model.} 29 | 30 | \item{cvs}{The covariates you would like to include in the model. 31 | Use a \code{c()} concatenated vector to use multiple covariates.} 32 | 33 | \item{df}{The dataframe where the columns from the formula can be found. 34 | Note that only the columns used in the analysis will be data screened.} 35 | 36 | \item{with_out}{A logical value where you want to keep the outliers in 37 | model \code{TRUE} or exclude them from the model \code{FALSE}.} 38 | 39 | \item{nboot}{A numeric value indicating the number of bootstraps you would like to complete.} 40 | 41 | \item{conf_level}{A numeric value indicating the confidence interval width for the boostrapped confidence interval.} 42 | } 43 | \description{ 44 | This function runs a complete serial mediation analysis with two 45 | mediators, similiar to model 6 in PROCESS by A. Hayes (2013). 46 | As part of the output, you will find data screening, 47 | all three models used in the traditional Baron and 48 | Kenny (1986) steps, total/direct/indirect effects, the z-score and p-value 49 | for the Aroian Sobel test, and the bootstrapped confidence interval 50 | for the indirect effect. 51 | } 52 | \examples{ 53 | mediation2(y = "Q11", x = "Q151", m1 = "Q31", m2 = "Q41", 54 | cvs = c("Q121"), df = mediation2_data, nboot = 1000, with_out = T, 55 | conf_level = .95) 56 | } 57 | \keyword{bootstrapping} 58 | \keyword{data} 59 | \keyword{mediation,} 60 | \keyword{regression,} 61 | \keyword{screening,} 62 | -------------------------------------------------------------------------------- /man/mediation2_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mediation2_data.R 3 | \docType{data} 4 | \name{mediation2_data} 5 | \alias{mediation2_data} 6 | \title{Mediation 2 Data} 7 | \format{A data frame of student evaluation ratings} 8 | \usage{ 9 | data(mediation2_data) 10 | } 11 | \description{ 12 | Dataset for use in \code{\link{mediation2}} example in MeMoBootR. 13 | These items were taken from student evaluations of teachers with 14 | 15 questions. ID represents a unique ID for each rating. 15 | } 16 | \keyword{datasets} 17 | -------------------------------------------------------------------------------- /man/mediation2_moda.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/mediation2_moda.R 3 | \name{mediation2_moda} 4 | \alias{mediation2_moda} 5 | \title{Two Mediations with Moderation on Path A} 6 | \usage{ 7 | mediation2_moda( 8 | y, 9 | x, 10 | m1, 11 | m2, 12 | mod, 13 | cvs = NULL, 14 | df, 15 | with_out = T, 16 | nboot = 1000, 17 | conf_level = 0.95 18 | ) 19 | } 20 | \arguments{ 21 | \item{y}{The dependent variable column name from your dataframe.} 22 | 23 | \item{x}{The independent variable column name from your dataframe. This column 24 | will be treated as X in mediation or moderation models, please see 25 | diagrams online for examples.} 26 | 27 | \item{m1}{The first mediator for your model.} 28 | 29 | \item{m2}{The second mediator for your model.} 30 | 31 | \item{cvs}{The covariates you would like to include in the model. 32 | Use a \code{c()} concatenated vector to use multiple covariates.} 33 | 34 | \item{df}{The dataframe where the columns from the formula can be found. 35 | Note that only the columns used in the analysis will be data screened.} 36 | 37 | \item{with_out}{A logical value where you want to keep the outliers in 38 | model \code{TRUE} or exclude them from the model \code{FALSE}.} 39 | 40 | \item{nboot}{A numeric value indicating the number of bootstraps you would like to complete.} 41 | 42 | \item{conf_level}{A numeric value indicating the confidence interval width for the boostrapped confidence interval.} 43 | } 44 | \description{ 45 | This function runs a serial mediation analysis with two mediators 46 | (model 6) with an added moderation on path a (like model 7) 47 | using the model numbers from A. Hayes (2013). 48 | As part of the output, you will find data screening, 49 | all model outputs used in the traditional Baron and 50 | Kenny (1986) steps, total/direct/indirect effects, 51 | the z-score and p-value 52 | for the Aroian Sobel test, and the bootstrapped confidence interval 53 | for the indirect effect. These are separated by simple slopes 54 | for the moderation part of the analysis. 55 | } 56 | \examples{ 57 | mediation2(y = "Q11", x = "Q151", m1 = "Q31", m2 = "Q41", mod = "Q121", 58 | cvs = NULL, df = mediation2_data, nboot = 1000, with_out = T, 59 | conf_level = .95) 60 | } 61 | \keyword{bootstrapping} 62 | \keyword{data} 63 | \keyword{mediation,} 64 | \keyword{regression,} 65 | \keyword{screening,} 66 | -------------------------------------------------------------------------------- /man/moderation1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/moderation1.R 3 | \name{moderation1} 4 | \alias{moderation1} 5 | \title{Two Way Moderation} 6 | \usage{ 7 | moderation1(y, x, m, cvs = NULL, df, with_out = T) 8 | } 9 | \arguments{ 10 | \item{y}{The dependent variable column name from your dataframe.} 11 | 12 | \item{x}{The independent variable column name from your dataframe. This column 13 | will be treated as X in mediation or moderation models, please see 14 | diagrams online for examples.} 15 | 16 | \item{m}{The moderator for your model, as this model only includes one moderator.} 17 | 18 | \item{cvs}{The covariates you would like to include in the model. 19 | Use a \code{c()} concatenated vector to use multiple covariates.} 20 | 21 | \item{df}{The dataframe where the columns from the formula can be found. 22 | Note that only the columns used in the analysis will be data screened.} 23 | 24 | \item{with_out}{A logical value where you want to keep the outliers in 25 | model \code{TRUE} or exclude them from the model \code{FALSE}.} 26 | } 27 | \description{ 28 | This function runs a complete two way moderation analysis with one 29 | moderator, similiar to model 1 in PROCESS by A. Hayes (2013). 30 | As part of the output, you will find data screening, 31 | the overall model, and the simple slopes for X at each level of the moderator. 32 | X and M variables will be mean centered after data screening and 33 | before analysis to control for multicollinearity unless they are categorical. 34 | } 35 | \examples{ 36 | states = as.data.frame(state.x77) 37 | moderation1(y = "Income", x = "Illiteracy", m = "Murder", 38 | cvs = c("Population", "Area"), df = states) 39 | } 40 | \keyword{bootstrapping} 41 | \keyword{data} 42 | \keyword{mediation,} 43 | \keyword{moderation,} 44 | \keyword{regression,} 45 | \keyword{screening,} 46 | -------------------------------------------------------------------------------- /man/moderation2.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/moderation2.R 3 | \name{moderation2} 4 | \alias{moderation2} 5 | \title{Double Two-Way Moderation} 6 | \usage{ 7 | moderation2(y, x, m1, m2, cvs = NULL, df, with_out = T) 8 | } 9 | \arguments{ 10 | \item{y}{The dependent variable column name from your dataframe.} 11 | 12 | \item{x}{The independent variable column name from your dataframe. This column 13 | will be treated as X in mediation or moderation models, please see 14 | diagrams online for examples.} 15 | 16 | \item{m1}{The first moderator for your model.} 17 | 18 | \item{m2}{The second moderator for your model.} 19 | 20 | \item{cvs}{The covariates you would like to include in the model. 21 | Use a \code{c()} concatenated vector to use multiple covariates.} 22 | 23 | \item{df}{The dataframe where the columns from the formula can be found. 24 | Note that only the columns used in the analysis will be data screened.} 25 | 26 | \item{with_out}{A logical value where you want to keep the outliers in 27 | model \code{TRUE} or exclude them from the model \code{FALSE}.} 28 | } 29 | \description{ 30 | This function runs a complete double two-way moderation analysis with two 31 | moderators, similiar to model 2 in PROCESS by A. Hayes (2013). 32 | As part of the output, you will find data screening, 33 | the overall model, and the simple slopes for X at each level of the moderator. 34 | X and M variables will be mean centered after data screening and 35 | before analysis to control for multicollinearity unless they are categorical. 36 | } 37 | \examples{ 38 | states = as.data.frame(state.x77) 39 | moderation2(y = "Income", x = "Illiteracy", m1 = "Murder", 40 | m2 = "Population", df = states) 41 | } 42 | \keyword{bootstrapping} 43 | \keyword{data} 44 | \keyword{mediation,} 45 | \keyword{moderation,} 46 | \keyword{regression,} 47 | \keyword{screening,} 48 | -------------------------------------------------------------------------------- /model numbers/model 1 CVs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 1 CVs.jpg -------------------------------------------------------------------------------- /model numbers/model 1 cat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 1 cat.png -------------------------------------------------------------------------------- /model numbers/model 1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 1.jpg -------------------------------------------------------------------------------- /model numbers/model 2 CVs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 2 CVs.jpg -------------------------------------------------------------------------------- /model numbers/model 2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 2.jpg -------------------------------------------------------------------------------- /model numbers/model 4 CVs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 4 CVs.jpg -------------------------------------------------------------------------------- /model numbers/model 4 cat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 4 cat.jpg -------------------------------------------------------------------------------- /model numbers/model 4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 4.jpg -------------------------------------------------------------------------------- /model numbers/model 6 CVs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 6 CVs.jpg -------------------------------------------------------------------------------- /model numbers/model 6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model 6.jpg -------------------------------------------------------------------------------- /model numbers/model numbers.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doomlab/MeMoBootR/0fb79e26bc220eb5f72703ec3c1d1cf36b25b26d/model numbers/model numbers.docx --------------------------------------------------------------------------------