% \VignetteIndexEntry{Overview of the psych package}
% \VignettePackage{psych}
% \VignetteKeywords{multivariate}
% \VignetteKeyword{models}
% \VignetteKeyword{Hplot}
%\VignetteDepends{psych}
%\documentclass[doc]{apa}
\documentclass[11pt]{article}
%\documentclass[11pt]{amsart}
\usepackage{geometry}                % See geometry.pdf to learn the layout options. There are lots.
\geometry{letterpaper}                   % ... or a4paper or a5paper or ... 
%\geometry{landscape}                % Activate for for rotated page geometry
\usepackage[parfill]{parskip}    % Activate to begin paragraphs with an empty line rather than an indent
\usepackage{graphicx}
\usepackage{amssymb}
\usepackage{epstopdf}
\usepackage{mathptmx}
\usepackage{helvet}
\usepackage{courier}
\usepackage{epstopdf}
\usepackage{makeidx}        % allows index generation
\usepackage[authoryear,round]{natbib} 
\usepackage{gensymb}
%\usepackage{longtable}
%\usepackage{geometry}   
\usepackage{amssymb}    
\usepackage{amsmath}
%\DeclareGraphicsRule{.tif}{png}{.png}{`convert #1 `dirname #1`/`basename #1 .tif`.png}
\usepackage[utf8]{inputenc}

\usepackage{Sweave}  
%\usepackage{/Volumes/'Macintosh HD'/Library/Frameworks/R.framework/Versions/2.13/Resources/share/texmf/tex/latex/Sweave}
%\usepackage[ae]{Rd}
%\usepackage[usenames]{color}
%\usepackage{setspace}


\bibstyle{apacite}
\bibliographystyle{apa}   %this one plus author year seems to work?
%\usepackage{hyperref}
\usepackage[colorlinks=true,citecolor=blue]{hyperref}  %this makes reference links hyperlinks in pdf!


\DeclareGraphicsRule{.tif}{png}{.png}{`convert #1 `dirname #1`/`basename #1 .tif`.png}
\usepackage{multicol}        % used for the two-column index
\usepackage[bottom]{footmisc}% places footnotes at page bottom
\let\proglang=\textsf
\newcommand{\R}{\proglang{R}}
%\newcommand{\pkg}[1]{{\normalfont\fontseries{b}\selectfont #1}}
\newcommand{\Rfunction}[1]{{\texttt{#1}}} 
\newcommand{\fun}[1]{{\texttt{#1}\index{#1}\index{R function!#1}}}
\newcommand{\pfun}[1]{{\texttt{#1}\index{#1}\index{R function!#1}\index{R function!psych package!#1}}}\newcommand{\Rc}[1]{{\texttt{#1}}}    %R command  same as Robject
\newcommand{\Robject}[1]{{\texttt{#1}}} 
\newcommand{\Rpkg}[1]{{\textit{#1}\index{#1}\index{R package!#1}}}   %different from pkg  - which is better?
\newcommand{\iemph}[1]{{\emph{#1}\index{#1}}} 
\newcommand{\wrc}[1]{\marginpar{\textcolor{blue}{#1}}}   %bill's comments
\newcommand{\wra}[1]{\textcolor{blue}{#1}}  %bill's comments

\newcommand{\ve}[1]{{\textbf{#1}}} %trying to get a vector command
\usepackage{fancyvrb}  %this allows fancy boxes

\newcommand{\vect}[1]{\boldsymbol{#1}}
\let\vec\vect

\fvset{fontfamily=courier}

\DefineVerbatimEnvironment{Routput}{Verbatim}
%{fontsize=\scriptsize, xleftmargin=0.6cm}
{fontseries=b,fontsize=\scriptsize, xleftmargin=0.1cm}

\DefineVerbatimEnvironment{Soutput}{Verbatim}
%{fontsize=\scriptsize, xleftmargin=0.6cm}
{fontseries=b,fontsize=\scriptsize, xleftmargin=0.1cm}


\DefineVerbatimEnvironment{Binput}{Verbatim}
{fontseries=b, fontsize=\scriptsize,frame=single, label=\fbox{lavaan model syntax}, framesep=2mm}

%\DefineShortVerb{\!} %%% generates error!

\DefineVerbatimEnvironment{Rinput}{Verbatim}
%{fontsize=\scriptsize, frame=single, label=\fbox{R code}, framesep=1mm}
{fontseries=b, fontsize=\scriptsize, frame=single, label=\fbox{R code},xleftmargin=0pt, framesep=1mm}

\DefineVerbatimEnvironment{Sinput}{Verbatim}
%{fontsize=\scriptsize, frame=single, label=\fbox{R code}, framesep=1mm}
{fontseries=b, fontsize=\scriptsize, frame=single, label=\fbox{R code},xleftmargin=0pt, framesep=1mm}

            
\DefineVerbatimEnvironment{Link}{Verbatim}
{fontseries=b, fontsize=\small, formatcom=\color{darkgreen}, xleftmargin=1.0cm}

\DefineVerbatimEnvironment{Toutput}{Verbatim}
{fontseries=b,fontsize=\tiny, xleftmargin=0.1cm}

\DefineVerbatimEnvironment{rinput}{Verbatim}
{fontseries=b, fontsize=\tiny, frame=single, label=\fbox{R code}, framesep=1mm}



\newcommand{\citeti}[1]{\begin{tiny}\citep{#1}\end{tiny}}

\newcommand{\light}[1]{\textcolor{gray}{#1}}

%\newcommand{\vect}[1]{\boldsymbol{#1}}
%\let\vec\vect
\makeindex         % used for the subject index

\title{How to use the psych package for regression and mediation analysis}
\author{William Revelle}

%the following works only with apaclass



   

\begin{document}
\maketitle
%\bibliography{all}


\tableofcontents
\newpage

\section{Overview of this and related documents}
To do basic and advanced personality and psychological research using \R{} is not as complicated as some think.  This is one of a set of ``How To'' to do various things using \R{} \citep{R}, particularly using the \Rpkg{psych} \citep{psych} package.


The current list of How To's includes:

\begin{enumerate}
\item An \href{http://personality-project.org/r/psych/intro.pdf}{introduction} (vignette) of the \Rpkg{psych} package 
\item An \href{http://personality-project.org/r/psych/overview.pdf}{overview} (vignette) of the \Rpkg{psych} package 
\item \href{http://personality-project.org/r/psych/HowTo/getting_started.pdf}{Installing} \R{}  and some useful packages
\item Using \R{} and the \Rpkg{psych} package to find \href{http://personality-project.org/r/psych/HowTo/omega.pdf}{$omega_h$} and $\omega_t$.
\item Using  \R{} and the \Rpkg{psych} for \href{http://personality-project.org/r/psych/HowTo/factor.pdf}{factor analysis} and principal components analysis.
\item Using the \pfun{scoreItems} function to find \href{http://personality-project.org/r/psych/HowTo/scoring.pdf}{scale scores and scale statistics}.
\item Using \pfun{mediate} and \pfun{lmCor} to do \href{http://personality-project.org/r/psych/HowTo/mediation.pdf}{mediation, moderation and regression analysis} (this document)


\end{enumerate}


\subsection{Jump starting the \Rpkg{psych} package--a guide for the impatient}

You have installed \Rpkg{psych}  and you want to use it without reading much more.  What should you do?

\begin{enumerate}
\item Activate the  \Rpkg{psych} and \Rpkg{psychTools} packages.


<<library>>==
library(psych)
library(psychTools)
@


\item Input your data.  If your file name ends in .sav, .text, .txt, .csv, .xpt, .rds, .Rds, .rda, or .RDATA, then just read it in directly using \pfun{read.file}.  Or you can go to your friendly text editor or data manipulation program (e.g., Excel) and copy the data to the clipboard.  Include a first line that has the variable labels.  Paste it into  \Rpkg{psych} using the \pfun{read.clipboard.tab} command:


\begin{Rinput}
myData <- read.file()    #this will open a search window on your machine 
#                                   and read or load the file. 
#or 
#first copy your file to your clipboard and then 
myData <- read.clipboard.tab()  #if you have an excel file 
\end{Rinput}


\item Make sure that what you just read is right.  Describe it  and perhaps look at the first and last few lines.  If you want to ``view" the first and last few lines using a spreadsheet like viewer, use \pfun{quickView}.


\begin{Rinput}
describe(myData)
headTail(myData) 
#or 
quickView(myData)
\end{Rinput}


\item Look at the patterns in the data. If you have fewer than about 10 variables, look at the SPLOM (Scatter Plot Matrix) of the data using \pfun{pairs.panels}.



\begin{Rinput}
pairs.panels(myData)
\end{Rinput}

\item Find the correlations of all of your data.  
\begin{itemize}
\item Descriptively (just the values)

\begin{Rinput}
lowerCor(myData)
\end{Rinput}


\item Graphically  


\begin{Rinput}

corPlot(myData)  #show the numbers,
                         #scales the character size by "significance"
corPlot(myData,scale=FALSE)  #show the numbers, 
                            #  all characters the same size
corPlot(lowerCor(myData), numbers =TRUE)   #print the correlations 
                        # and show them graphically
\end{Rinput}

\end{itemize}

\end{enumerate}

\subsection{For the not impatient}
The following pages are meant to lead you through the use of the \pfun{lmCor} and \pfun{mediate} functions.  The assumption is that you have already made \Rpkg{psych} active and want some example code. 

\section{Multiple regression and mediation}

Mediation and moderation are merely different uses of the linear model  $\hat{\vec{Y}}= \mu + \beta_{y.x} \vec{X } + \vec{\epsilon} $ and are implemented in \Rpkg{psych} with two functions: \pfun{lmCor} and \pfun{mediate}.  

Given a set of predictor variables, $\vec{X}$ and a set of criteria variables, $\vec{Y}$, multiple regression solves the equation $\hat{\vec{Y}} = \mu + \beta_{y.x} \vec{X } $ by finding $\beta_{y.x} = \vec{C_{xx}}^{-1} C_{yx} $ where $\vec{C_{xx}}$ is the covariances of the $\vec{X}$ variables and $\vec{C_{yx}}$ is the covariances of predictors and the criteria.  

Although typically done using the raw data, clearly this can also be done by using the covariance or correlation matrices.  \pfun{lmCor} was developed to handle the correlation matrix solution but has been generalized to the case of raw data.  In the later case, it assumes a Missing Completely at Random (MCAR) structure, and thus uses all the data and finds pair.wise complete correlations.   For complete data sets, the results are identical to using \pfun{lm}.  By default, \pfun{lmCor} uses standardized variables, but to compare with \pfun{lm}, it can use unstandardized variables.



\section{Regression using \pfun{lmCor}}

Although typically done from a raw data matrix (using the \fun{lm} function), it is sometimes useful to do the regression from a correlation or covariance matrix. \pfun{lmCor} was developed for this purpose.  From a correlation/covariance matrix, it will do normal regression as well as regression on partialled correlation matrices.  With the raw data, it will also do moderated regression (centered or non-centered). In particular, for the raw data, it will work with missing data.

An interesting option, if using categorical or dichotomous data is first find the appropriate polychoric, tetrachoric, or poly-serial correlations using \pfun{mixedCor} and then use the resulting correlation matrix for analysis. The resulting correlations and multiple correlations will not match those of the \pfun{lm} analysis. 

\subsection{Comparison with \pfun{lm} on complete data}

Use the \pfun{attitude} data set for our first example.

\subsubsection{It is important to know your data by describing it first}

<<attitude>>==
psych::describe(attitude)
@ 
\subsubsection{Now do the regressions}

<<attitude>>==
 #do not standardize
mod1 <- lmCor(rating ~ complaints + privileges, data=attitude,std=FALSE)
mod1
@

Compare this solution with the results of the \pfun{lm} function.

<<attitudelm>>==
summary(lm(rating ~ complaints + privileges, data=attitude))
@



The graphic for the standardized regression is shown in (Figure~\ref{fig:attitude}).

<<attitude, echo=FALSE, print=FALSE>>==
png('attitude.png')
# standardize by default
mod2 <- lmCor(rating ~ complaints + privileges, data=attitude) 
mod2
diagram(mod2, main="A simple regression model")
dev.off()
@


\begin{figure}[htbp]
\begin{center}
\includegraphics{attitude.png}
\caption{A simple multiple regression using the attitude data set (standardized solution is shown).}
\label{fig:attitude}
\end{center}
\end{figure}


\subsection{From a correlation matrix}

Perhaps most usefully, \pfun{lmCor} will find the beta weights between a set of X variables, and a set of Y variables.  Consider seven variables in the \pfun{atttitude} data set.   We first find the correlation matrix (normally, this could just be supplied by the user).  Then we find the regressions from the correlation matrix.  Compare this regression to the (standardized) solution shown above.   By specifying the number of observations (n.obs), we are able to apply various inferential tests.

<<attitudeR>>==
R <- lowerCor(attitude) 

 lmCor(rating ~ complaints + privileges, data=R, n.obs =30)
@


Compare this solution (from the correlation matrix) with the \emph{standardized} solution for the raw data. 
\pfun{lmCor} does several things: 

\begin{itemize}
\item Finds the regression weights (betas) between the predictor variables and each of the criterion variables.
\item If the number of subjects is specified, or if the raw data are used, it also compares each of these betas to its standard error, finds a $t$ statistic, and reports the probability of the $|t| > 0$.  
\item It reports the Multiple R and $R^2$  based upon these beta weights.  In addition, following the tradition of the robust beauty of the improper linear models \citep{dawes:79} it also reports the unit weighted multiple correlations.
\item If there are more than 1 Y variables, the canonical correlations between the two sets (X and Y)  \citep{hotelling:36} arereported.  The canonical loadings are reported in the Xmat and Ymat objects.
\item Cohen's set correlation \citep{cohen:82} as well as the unweighted correlation between the two sets of variables are reported.

\end{itemize}


\subsection{The Hotelling example} 
<<kelley>>==

#the second Kelley data from Hotelling
kelley <- structure(list(speed = c(1, 0.4248, 0.042, 0.0215, 0.0573), power = c(0.4248, 
1, 0.1487, 0.2489, 0.2843), words = c(0.042, 0.1487, 1, 0.6693, 
0.4662), symbols = c(0.0215, 0.2489, 0.6693, 1, 0.6915), meaningless = c(0.0573, 
0.2843, 0.4662, 0.6915, 1)), .Names = c("speed", "power", "words", 
"symbols", "meaningless"), class = "data.frame", row.names = c("speed", 
"power", "words", "symbols", "meaningless"))

#first show the correlations
lowerMat(kelley)

#now find and draw the regression
sc <- lmCor(power + speed ~ words + symbols + meaningless,data=kelley)  #formula mode
sc  #show it
@


%First show the correlation matrix.
%\begin{Routput}
%
%lowerMat(kelley)
%            speed power words symbl mnngl
%speed        1.00                        
%power        0.42  1.00                  
%words        0.04  0.15  1.00            
%symbols      0.02  0.25  0.67  1.00      
%meaningless  0.06  0.28  0.47  0.69  1.00
%\end{Routput}
%
%Now, use the \pfun{lmCor} function.
%
%\begin{Routput}
%Call: lmCor(y = power + speed ~ words + symbols + meaningless, data = kelley)
%
%Multiple Regression from matrix input 
%
% DV =  power 
%            slope  VIF
%words       -0.03 1.81
%symbols      0.12 2.72
%meaningless  0.22 1.92
%
% Multiple Regression
%         R   R2  Ruw R2uw
%power 0.29 0.09 0.26 0.07
%
% DV =  speed 
%            slope  VIF
%words        0.05 1.81
%symbols     -0.07 2.72
%meaningless  0.08 1.92
%
% Multiple Regression
%         R   R2  Ruw R2uw
%speed 0.07 0.01 0.05    0
%
%Various estimates of between set correlations
%Squared Canonical Correlations 
%[1] 0.0946 0.0035
%
% Average squared canonical correlation =  0.05
% Cohen's Set Correlation R2 =  0.1
%Unweighted correlation between the two sets =  0.18
%
%\end{Routput}

A plot of the regression model is shown as well (Figure~\ref{fig:hotelling}).


<<kelly, echo=FALSE, print=FALSE>>==
png('hotelling.png')
lmDiagram(sc, main="The  Kelley data set")
dev.off()
@

\begin{figure}[htbp]
\begin{center}
\includegraphics{hotelling.png}
\caption{The relationship between three predictors and two criteria from \pfun{lmCor}.  The data are from the Kelley data set reported by \cite{hotelling:36}.}
\label{fig:hotelling}
\end{center}
\end{figure}

\subsection{Canonical Correlation using \pfun{lmCor}}

A  generalization of multiple regression to multiple predictors and multiple criteria is \iemph{canonical correlation} \citep{hotelling:36}. Given a partitioning of a correlation matrix, R, into Rxx, Ryy and Rxy, canonical correlation  finds orthogonal components of the correlations between the Rx and Ry sets (the Rxy correlations).    Consider the Kelley data set discussed by \cite{hotelling:36} who introduced the canonical correlation.  This analysis is shown in help menu for \pfun{lmCor}.  Another data set is the  ``Belly Dancer" data set discussed by \cite{Tabachnick:01} (Chapter 12).   Here I show the data, the correlations, the regressions, and the canonical correlations. 

\begin{scriptsize}
<<echo=TRUE>>=

dancer  <- structure(list(TS = c(1, 7, 4.6, 1, 7, 7, 7, 7), TC = c(1, 1, 
5.6, 6.6, 4.9, 7, 1, 1), BS = c(1, 7, 7, 1, 7, 6.4, 7, 2.4), 
    BC = c(1, 1, 7, 5.9, 2.9, 3.8, 1, 1)), class = "data.frame", row.names = c(NA, 
-8L))
dancer   #show the data

model <- psych::lmCor(TC + TS ~ BC + BS, data = dancer)
summary(model)  #show the summary statistics
round(model$Xmat,2) #the X canonical loadings
round(model$Ymat,2) #the Y canonical loadings
cancorDiagram(model, main="Canonical correlations for the 'Belly Dancer' example") #and the associated canonical figure

@
\end{scriptsize}

\begin{figure}[htbp]
\begin{center}
\begin{scriptsize}
<<dancer>>=
png('dancerlm.png')
model <- psych::lmCor(TC + TS ~ BC + BS, data = dancer)
  dev.off()
@
\end{scriptsize}
\includegraphics{dancerlm.png}
\caption{Multiple regression of the Belly Dancer data set.  Compare with the canonical correlation figure \ref{fig:cancor}  }
\label{fig:lm}
\end{center}
\end{figure}

\begin{figure}[htbp]
\begin{center}
\begin{scriptsize}
<<dancer>>=
png('dancer.png')
cancorDiagram(model)
  dev.off()
@
\end{scriptsize}
\includegraphics{dancer.png}
\caption{Canonical Correlation of the  Belly Dancer data set.  Compare with the linear regression figure  \ref{fig:lm}   }
\label{fig:cancor}
\end{center}
\end{figure}



%\subsection{From the raw data}
%
%
%
%If the data are available, \pfun{setCor} will find the regressions between variables in an X set and those in a Y set.  The first analysis  (Figure~\ref{fig:2pred}) is perhaps the more typical (one criterion, two predictors), while the second example is more complicated, with three predictors of 3 dependent variables (Figure~\ref{fig:3x3}).
%
%
%<<satact>>==
%mod2  <- setCor(ACT ~ SATV + SATQ, data=sat.act)
%mod2
%@
%
%<<satactfig, echo=FALSE, print=FALSE>>==
%png('mod2.png')
%setCor.diagram(mod2, main="Regressions for sat.act data")
%dev.off()
%@
%
%\begin{Rinput}
%
%#  a  typical use of setCor
%mod2  <- setCor(ACT ~ SATV + SATQ, data=sat.act)
%mod2
%\end{Rinput}
%\begin{Routput}
%Call: setCor(y = ACT ~ SATV + SATQ, data = sat.act)
%
%Multiple Regression from raw data 
%
% DV =  ACT 
%     slope   se     t       p  VIF
%SATV  0.31 0.04  8.09 2.7e-15 1.72
%SATQ  0.39 0.04 10.08 0.0e+00 1.72
%
% Multiple Regression
%       R  R2  Ruw R2uw Shrunken R2 SE of R2 overall F df1 df2 p
%ACT 0.63 0.4 0.63  0.4         0.4     0.03    234.26   2 697 0
%\end{Routput}

%\begin{figure}[htbp]
%\begin{center}
%\includegraphics{mod2.png}
%\caption{The relationship between two predictors and one criterion from \pfun{setCor}.  The data are from the \pfun{sat.act} data set }
%\label{fig:2pred}
%\end{center}
%\end{figure}
%

But, we can also do multiple predictors \emph{and} multiple criteria in the same call:


<<satact,  echo=FALSE, print=FALSE>>==
png('satact.png')
mod3 <- lmCor(SATV + SATQ + ACT ~ gender + education + age, data = sat.act)
dev.off()
@


%<<satgraoguc, echo=FALSE, print=FALSE>>==
%png('satact.png')
%setCor.diagram(mod3, main="Three predictors, 3 criteria")
%dev.off()
@
%\begin{Rinput}
%mod3 <- setCor(SATV + SATQ + ACT ~ gender + education + age, data = sat.act)
%
%\end{Rinput}
%
%\begin{Routput}
%Multiple Regression from raw data 
%
% DV =  SATV 
%          slope   se     t     p  VIF
%gender    -0.03 0.04 -0.79 0.430 1.01
%education  0.10 0.05  2.29 0.022 1.45
%age       -0.10 0.05 -2.21 0.028 1.44
%
% Multiple Regression
%       R   R2  Ruw R2uw Shrunken R2 SE of R2 overall F df1 df2      p
%SATV 0.1 0.01 0.05    0        0.01     0.01      2.26   3 696 0.0808
%
% DV =  SATQ 
%          slope   se     t       p  VIF
%gender    -0.18 0.04 -4.71 3.0e-06 1.01
%education  0.10 0.04  2.25 2.5e-02 1.45
%age       -0.09 0.04 -2.08 3.8e-02 1.44
%
% Multiple Regression
%        R   R2  Ruw R2uw Shrunken R2 SE of R2 overall F df1 df2        p
%SATQ 0.19 0.04 0.11 0.01        0.03     0.01      8.63   3 696 1.24e-05
%
% DV =  ACT 
%          slope   se     t      p  VIF
%gender    -0.05 0.04 -1.28 0.2000 1.01
%education  0.14 0.05  3.14 0.0017 1.45
%age        0.03 0.04  0.71 0.4800 1.44
%
% Multiple Regression
%       R   R2  Ruw R2uw Shrunken R2 SE of R2 overall F df1 df2        p
%ACT 0.16 0.03 0.15 0.02        0.02     0.01      6.49   3 696 0.000248
%
%Various estimates of between set correlations
%Squared Canonical Correlations 
%[1] 0.050 0.033 0.008
%Chisq of canonical correlations 
%[1] 35.8 23.1  5.6
%
% Average squared canonical correlation =  0.03
% Cohen's Set Correlation R2 =  0.09
% Shrunken Set Correlation R2 =  0.08
% F and df of Cohen's Set Correlation  7.26 9 1681.86
%Unweighted correlation between the two sets =  0.01
%
%\end{Routput}
%


\begin{figure}[htbp]
\begin{center}
\includegraphics{satact.png}
\caption{The relationship between three predictors and three criteria from \pfun{lmCor}.  The data are from the \pfun{sat.act} data set.}
\label{fig:3x3}
\end{center}
\end{figure}

\subsection{Graphic displays}

When considering the within group relationships for multiple groups, (e.g., gender or grade level) it is useful to draw separate regression lines for each group.  Consider the case of the regression of age on  paragraph comprehension as a function of class grade (6 or 7) in the \pfun{holzinger.swineford} data set in \Rpkg{psychTools}.   
  
<<suppressor echo=TRUE, print=FALSE>>== 
 lowerCor(holzinger.swineford[c(3,7,12:14)])
@
  It would seem as if both age and grade account for 4\% of the variance in paragraph comprehension.  But combining these two in a multiple regression increases the variance explained from 8\% (the sum of the two)  to 18\%, because age and grade suppress variance unrelated to cognitive performance.  
  
  Show this finding in two different ways: as a plot of the separate regression lines Figure~\ref{fig:hs} for each grade or as a simple path model Figure~\ref{fig:hsp}  .
  Note that because grade goes from 7 to 8, to index the colors in the plot we subtract 6 from both grades to get a 1, 2 variable.


<<hs  echo=FALSE, print=FALSE>>==
png('hs.png')
plot(t07_sentcomp ~ agemo, col=c("red","blue")[holzinger.swineford$grade -6],
  pch=26-holzinger.swineford$grade,data=holzinger.swineford,
   ylab="Sentence Comprehension",xlab="Age in Months",
   main="Sentence Comprehension varies by age and grade")
by(holzinger.swineford, holzinger.swineford$grade -6,function(x) abline(
     lmCor(t07_sentcomp ~ agemo,data=x, std=FALSE, plot=FALSE) ,lty=c("dashed","solid")[x$grade-6]))
text(190,3.3,"grade = 8")
text(190,2,"grade = 7") 
dev.off()
@

<<hsp  echo=FALSE, print=FALSE>>==
png('hsp.png') 
 lmCor(t07_sentcomp ~ agemo + grade,data=holzinger.swineford) 
dev.off()
@

\begin{figure}[htbp]
\begin{center}
\includegraphics{hs.png}
\caption{Showing a multiple regression using  \pfun{lmCor} with lines for each group.  The data are from the \pfun{holzinger:swineford} data set.  Although age and grade are highly correlated (.53) grade has a positive effect age a negative effect.}
\label{fig:hs}
\end{center}
\end{figure}


To show just the coefficients of this model, do the regressions without the plot, turn off the plot option:

<<lm echo=FALSE, print=TRUE>>==
by(holzinger.swineford,holzinger.swineford$grade,function(x) 
     lmCor(t07_sentcomp ~ agemo,data=x, std=FALSE, plot=FALSE) )
@

\begin{figure}[htbp]
\begin{center}
\includegraphics{hsp.png}
\caption{The regression of age and grade on paragraph comprehension.   The data are from the \pfun{holzinger:swineford} data set.  Although age and grade are highly correlated (.53) grade has a positive effect age a negative effect.  Here we show the standardized regressions.  In the previous figure we show the raw (understanderized) slopes. }
\label{fig:hsp}
\end{center}
\end{figure}








\subsection{Moderated multiple regression}

With the raw data, find interactions (known as moderated multiple regression).   This is done by zero centering the data \citep{cohen:03} and then multiplying the two terms of the interaction.  As an option, do not zero center the data \citep{hayes:13} which results in different ``main effects" but the same interaction term.  To show the equivalence of the interaction terms, we also must not standardize the results. 

Use the \pfun{globalWarm} data set taken from \citep{hayes:13}
<<moderation>>==
mod <-lmCor(govact ~ negemot * age + posemot +ideology+sex,data=globalWarm,
          std=FALSE, zero=FALSE, plot=FALSE)
mod
mod0 <- lmCor(govact ~ negemot * age + posemot +ideology+sex,data=globalWarm,std=FALSE, plot=FALSE)
mod0
@

<<modplot, echo=FALSE, print=FALSE>>==
png('moderation.png')
lmDiagram(mod, main="not zero centered")
dev.off()
@
<<modplot1, echo=FALSE, print=FALSE>>==
png('moderation0.png')
diagram(mod0, main="zero centered")
dev.off()
@

\begin{figure}[htbp]
\begin{center}
\includegraphics{moderation.png}
\caption{Showing a moderated multiple regression using  \pfun{lmCor}.  The data are from the \pfun{globalWarm} data set.}
\label{fig:mod}
\end{center}
\end{figure}

%\begin{Routput}
%Call: setCor(y = SATQ ~ SATV * gender + ACT, data = sat.act, std = FALSE)
%
%Multiple Regression from raw data 
%
% DV =  SATQ 
%             slope   se     t       p  VIF
%SATV          0.47 0.03 14.47 0.0e+00 1.46
%gender      -35.08 6.40 -5.48 6.0e-08 1.00
%ACT           7.72 0.77 10.05 0.0e+00 1.47
%SATV*gender  -0.03 0.06 -0.47 6.4e-01 1.01
%
% Multiple Regression
%        R   R2   Ruw    R2uw Shrunken R2 SE of R2 overall F df1 df2 p
%SATQ 0.72 0.51 70.33 4946.43        0.51     0.03    183.23   4 695 0
%
%
%Call: setCor(y = SATQ ~ SATV * gender + ACT, data = sat.act, std = FALSE, 
%    zero = FALSE)
%
%Multiple Regression from raw data 
%
% DV =  SATQ 
%             slope    se     t       p   VIF
%SATV          0.52  0.10  5.20 2.7e-07 13.52
%gender      -18.71 35.31 -0.53 6.0e-01 30.44
%ACT           7.72  0.77 10.05 0.0e+00  1.47
%SATV*gender  -0.03  0.06 -0.47 6.4e-01 41.50
%
% Multiple Regression
%        R   R2   Ruw    R2uw Shrunken R2 SE of R2 overall F df1 df2 p
%SATQ 0.72 0.51 40.02 1601.68        0.51     0.03    183.23   4 695 0
%
%\end{Routput} 

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=7cm]{moderation.png}
\includegraphics[width=7cm]{moderation0.png}


\caption{The difference between 0 and not 0 centering \pfun{lmCor}.  The data are from the \pfun{globalWarm} data set. In both cases, the data are not standarized.}
\label{default}
\end{center}
\end{figure}

\subsection{Plotting the interactions}

To visualize the effect of zero (mean) centering, it is useful to plot the various elements that go into the linear model.  \pfun{lmCor} returns the product terms as well as the original data.  Combine  the two datasets to make it clearer. Note that the correlations of the centered age, negemot  with the uncentered are 1.0, but that the correlations with the product terms depend upon centering versus not. Drop some of the other  variables from the figure for clarity (Figure~\ref{fig:splom}).

<<plotting,  echo=FALSE, print=FALSE>>==
both <- cbind(mod$data[,-1],mod0$data[,-1])
png('splom.png')
pairs.panels(both[,-c(4,5,6,8,11:13)])  #show the mean centered data
dev.off()
@

\begin{figure}[htbp]
\begin{center}
\includegraphics{splom.png}
\caption{The effect of not mean centering versus mean centering on the product terms.  The first four variables were not zero centered, the second four were. }
\label{fig:splom}
\end{center}
\end{figure}

\subsection{Comparisons to \fun{lm}}

The \pfun{lmCor} function duplicates the functionality of the \fun{lm} function  for complete data, although \fun{lm} does not zero center and \pfun{lmCor} will (by default). In addition, \pfun{lmCor} finds correlations based upon pair.wise deletion of missing data, while \fun{lm} does case.wise deletion.  We compare the \fun{lm} and \pfun{lmCor} results for complete data by setting the \texttt{ use = "complete"} option.  Use the \pfun{sat.act} data set which has some missing values.



<<setcorvslm>>==

summary(lm(SATQ ~ SATV*gender + ACT, data=sat.act))
mod <- lmCor(SATQ ~ SATV*gender + ACT, data=(sat.act), zero=FALSE, std=FALSE,use="complete")
print(mod,digits=5)
@

% lm(SATQ ~ SATV*gender + ACT, data=sat.act)
%Call:
%lm(formula = SATQ ~ SATV * gender + ACT, data = sat.act)
%
%Coefficients:
%(Intercept)         SATV       gender          ACT  SATV:gender  
%  138.52395      0.50280    -22.24995      7.71702     -0.01984  
%
%> mod <- setCor(SATQ ~ SATV*gender + ACT, data=(sat.act), zero=FALSE, std=FALSE,use="complete")
%
%print(mod,digits=5)
%Call: setCor(y = SATQ ~ SATV * gender + ACT, data = (sat.act), use = "complete", 
%    std = FALSE, zero = FALSE)
%
%Multiple Regression from raw data 
%
% DV =  SATQ 
%                slope       se        t          p      VIF
%SATV          0.50280  0.09936  5.06050 5.3589e-07 13.43994
%gender      -22.24995 35.25783 -0.63106 5.2821e-01 30.29663
%ACT           7.71702  0.76977 10.02511 0.0000e+00  1.46678
%SATV*gender  -0.01984  0.05652 -0.35105 7.2566e-01 41.25607
%
% Multiple Regression
%           R   R2      Ruw     R2uw Shrunken R2 SE of R2 overall F df1 df2 p
%SATQ 0.71414 0.51 39.93879 1595.107     0.50718  0.02621  180.8401   4 695 0
%\end{Routput}

\section{Mediation using  the \pfun{mediate} function}

Mediation analysis is just linear regression reorganized slightly to show the direct effects of an X variable upon Y, partialling  out the effect of a ``mediator" (Figure~\ref{fig:mediation}).  Although the statistical ``significance" of  the (c) path and the (c') path are both available from standard regression, the mediation effect (ab) is best found by boot strapping the regression model and displaying the empirical confidence intervals.

 
\begin{figure}[htbp]
\begin{center}
\begin{picture}(200,200)
\put(10,50){\framebox(20,20){$X_{1}$}}
\put(85,123){\framebox(20,20){$M_{1}$}}
\put(160,50){\framebox(20,20){$Y_{1}$}}
\put(30,70){\vector(1,1){54}}
\put(105,123){\vector(1,-1){54}}
\put(30,60){\vector(1,0){130}}

\put(50,98){a}
\put(134,98){b}
\put(95,65){c}
\put(78,51){c'= c - ab}
\end{picture}

\caption{The classic mediation model. The Direct Path  from X -> Y (c) is said to be mediated by the indirect path (a) to the mediator  (X -> M) and (b) from the mediator to Y (M -> Y).  The mediation effect is  (ab). }
\label{fig:mediation}
\end{center}
\end{figure}

 A number of papers discuss how to test for the effect of mediation and there are some very popular `macros' for SPSS and SAS to do so \citep{hayes:13,preacher:04,preacher:07,preacher:15}.  A useful discussion of mediation and moderation with sample data sets is found in \cite{hayes:13}. More recently, the \Rpkg{processR} package \citep{processR} has been released with these data sets.  Although these data used to be be available from   \href{"http://www.afhayes.com/public/hayes2018data.zip"}{http://www.afhayes.com/public/hayes2018data.zip}  this now longer seems to be case.\footnote{The Hayes data sets (2018) do not correspond exactly with those from the 2013 book. Those data files were at  \href{"http://www.afhayes.com/public/hayes2013data.zip"}{http://www.afhayes.com/public/hayes2013data.zip}.}.  I use these for comparisons with the results in \cite{hayes:13}.  Four of these data sets are now included in the \Rpkg{psych} package with the kind permission of their authors: \pfun{Garcia} is from \cite{garcia:10}, and \pfun{Tal\_Or} is from \cite{talor:10},  The \pfun{Pollack} correlation matrix is taken from an article by \cite{pollack:12}.   The \pfun{globalWarm} data set is the \pfun{glbwarm} data set in the  \Rpkg{processR} package and added to \Rpkg{psychTools} with the kind permission of the original author, Erik Nisbet.   



To find the confidence intervals of the effect  of mediation (the reduction between the c and c' paths, where c' = c - ab), bootstrap the results by randomly sampling from the data with replacement  (e.g n.iter = 5000) times.

For these examples, the data files \pfun{Garcia}  \citep{garcia:10} and  \pfun{Tal\_Or} \citep{talor:10} are included in the \pfun{psych} package.  The \pfun{estrss} data set  and \pfun{globalWarm} were originally downloaded from the    \cite{hayes:13} data sets.  The correlation matrix for the \pfun{estress} data set is stored as \pfun{Pollack} in the \pfun{psychTools} package as is the \pfun{Globalwarm} data set. They are also available from the \Rpkg{processR} package \cite{processR}. 

The syntax is that $ y \sim  x + (m) $ where m is the mediating variable.  By default the output is to two decimals, as is the graphic output.  This can be increased by returning the output to an object and then printing that object with the desired number of decimals.



\subsection{Simple mediation} 

The first example \citep[mod.4.5]{hayes:13} is taken from \citep{talor:10} and examines the mediating effect of ``Presumed Media Influence'' (pmi) on the intention to act  (reaction) based upon the importance of a message (import).   The data are in the \pfun{Tal\_Or} data set in \Rpkg{psych} (with the kind permission of Nurit Tal-Or, Jonanathan Cohen, Yariv Tasfati, and Albert Gunther).  In the \cite{hayes:13} book, this is the \pfun{pmi} data set.

<<Tak_Or>>==
data(Tal.Or) 
psych::describe(Tal_Or)  #descriptive statistics

mod4.4 <- mediate(reaction ~ cond + (pmi), data =Tal_Or)
mod4.4
#print(mod4.4, digits = 4) # in order to get the precision of the Hayes (2013) p 99 example
@
%\begin{Routput}
%data(Tal_Or) 
%describe(Tal_Or)  #descriptive statistics
%         vars   n  mean   sd median trimmed  mad min max range  skew kurtosis   se
%cond        1 123  0.47 0.50   0.00    0.46 0.00   0   1     1  0.11    -2.00 0.05
%pmi         2 123  5.60 1.32   6.00    5.78 1.48   1   7     6 -1.17     1.30 0.12
%import      3 123  4.20 1.74   4.00    4.26 1.48   1   7     6 -0.26    -0.89 0.16
%reaction    4 123  3.48 1.55   3.25    3.44 1.85   1   7     6  0.21    -0.90 0.14
%gender      5 123  1.65 0.48   2.00    1.69 0.00   1   2     1 -0.62    -1.62 0.04
%age         6 123 24.63 5.80  24.00   23.76 1.48  18  61    43  4.71    24.76 0.52
%
%
% mod4.4 <- mediate(reaction ~ cond + (pmi), data =Tal_Or)
%> mod4.4
%Mediation/Moderation Analysis 
%Call: mediate(y = reaction ~ cond + (pmi), data = Tal_Or)
%
%The DV (Y) was  reaction . The IV (X) was  cond . The mediating variable(s) =  pmi .
%
%Total effect(c) of  cond  on  reaction  =  0.5   S.E. =  0.28  t  =  1.79  df=  120   with p =  0.077
%Direct effect (c') of  cond  on  reaction  removing  pmi  =  0.25   S.E. =  0.26 
%            t  =  0.99  df=  120   with p =  0.32
%Indirect effect (ab) of  cond  on  reaction  through  pmi   =  0.24 
%Mean bootstrapped indirect effect =  0.24  with standard error =  0.13  Lower CI =  0    Upper CI =  0.52
%R = 0.45 R2 = 0.21   F = 15.56 on 2 and 120 DF   p-value:  9.83e-07 
%
% To see the longer output, specify short = FALSE in the print statement or ask for the summary
%
% Full output  
% Total effect estimates (c) 
%     reaction   se    t  df   Prob
%cond      0.5 0.28 1.79 120 0.0766
%
%Direct effect estimates     (c') 
%     reaction   se    t  df     Prob
%cond     0.25 0.26 0.99 120 3.22e-01
%pmi      0.51 0.10 5.22 120 7.66e-07
%
%R = 0.45 R2 = 0.21   F = 15.56 on 2 and 120 DF   p-value:  9.83e-07 
%
% 'a'  effect estimates 
%      pmi   se    t  df   Prob
%cond 0.48 0.24 2.02 121 0.0454
%
% 'b'  effect estimates 
%    reaction  se    t  df     Prob
%pmi     0.51 0.1 5.22 120 7.66e-07
%
% 'ab'  effect estimates 
%     reaction boot   sd lower upper
%cond     0.24 0.24 0.13     0  0.52
%
%\end{Routput}

<<ned99,  echo=FALSE, print=FALSE>>==
png('mediate99.png')
mediate.diagram(mod4.4)
dev.off()
@


\begin{figure}[htbp]
\begin{center}
\includegraphics{mediate99.png}
\caption{A simple mediation model \citep[p 99] {hayes:13} with data derived from \cite{talor:10}. The effect of a salience manipulation (cond) on the intention to buy a product (reaction) is mediated through the presumed media influence (pmi).}
\label{default}
\end{center}
\end{figure}

A second example from \citep{hayes:13} is an example of moderated mediated effect.  The data are from \citep{garcia:10} and report on the effect of protest on reactions to a case of sexual discrimination.  

<<garcia>>==
data(GSBE)  #alias to Garcia data set
#compare two models  (bootstrapping n.iter set to 50 for speed
# 1) mean center the variables prior to taking product terms
mod1 <- mediate(respappr ~ prot2 * sexism +(sexism),data=Garcia,n.iter=50
 ,main="Moderated mediation (mean centered)")
# 2) do not mean center
mod2 <- mediate(respappr ~ prot2 * sexism +(sexism),data=Garcia,zero=FALSE, n.iter=50,   
    main="Moderated  mediation (not centered")
summary(mod1)
summary(mod2)
@



%A second example of simple mediation from \cite[p 118-121]{hayes:13} is the effect of economic stress.  The original data are from a study by \cite{pollack:12} and are available from the \cite{hayes:13} website.  Is the effect of economic stress (estress) on subsequent disengagement from entreprenuerial activities (withdraw) mediated through depressed affect (affect)?  
%
%\begin{Rinput}
%estress <- read.file() #read the external file
%describe(estress)
%mod4.5 <- mediate(withdraw ~ estress + (affect), data =estress)
%mod4.5 #normal printing is to 2 decimals
%#  and show the graphic to 2 decimals
%#print(mod4.5, digits=4) #print to four decimals to confirm output with Hayes
%#mediate.diagram(mod4.5,digits=3) to show the graphic to 3 decimals
%
%\end{Rinput}
%
%\begin{Routput}
%estress <- read.file()
%re-encoding from CP1252
%Data from the SPSS sav file"
% /Users/WR/Box Sync/pmc_folder/tutorials/HowTo/mediation/hayes2018data/estress/estress.sav has been loaded.
%> describe(estress)
%         vars   n  mean    sd median trimmed   mad   min max range  skew kurtosis   se
%tenure      1 262  5.93  6.58   4.00    4.73  5.07  0.00  33 33.00  1.64     2.67 0.41
%estress     2 262  4.62  1.42   4.50    4.66  1.48  1.00   7  6.00 -0.27    -0.49 0.09
%affect      3 262  1.60  0.72   1.33    1.46  0.49  1.00   5  4.00  1.97     4.57 0.04
%withdraw    4 262  2.32  1.25   2.00    2.19  1.48  1.00   7  6.00  0.70    -0.17 0.08
%sex         5 262  0.62  0.49   1.00    0.65  0.00  0.00   1  1.00 -0.48    -1.77 0.03
%age         6 262 43.79 10.36  44.00   43.78 11.86 23.00  71 48.00 -0.01    -0.82 0.64
%ese         7 262  5.61  0.94   5.73    5.67  1.08  2.53   7  4.47 -0.55    -0.13 0.06
%
%\end{Routput}
%\begin{Toutput}
%mod4.5
%
%Mediation/Moderation Analysis 
%Call: mediate(y = withdraw ~ estress + (affect), data = estress)
%
%The DV (Y) was  withdraw . The IV (X) was  estress . The mediating variable(s) =  affect .
%
%Total effect(c) of  estress  on  withdraw  =  0.06   S.E. =  0.05  t  =  1.04  df=  259   with p =  0.3
%Direct effect (c') of  estress  on  withdraw  removing  affect  =  -0.08   S.E. =  0.05  t  =  -1.47  df=  259   with p =  0.14
%Indirect effect (ab) of  estress  on  withdraw  through  affect   =  0.13 
%Mean bootstrapped indirect effect =  0.13  with standard error =  0.03  Lower CI =  0.07    Upper CI =  0.2
%R = 0.42 R2 = 0.18   F = 28.49 on 2 and 259 DF   p-value:  6.53e-12 
%\end{Toutput}
%\begin{Routput}
% Full output  
% Total effect estimates (c) 
%        withdraw   se    t  df  Prob
%estress     0.06 0.05 1.04 259 0.302
%
%Direct effect estimates     (c') 
%        withdraw   se     t  df     Prob
%estress    -0.08 0.05 -1.47 259 1.44e-01
%affect      0.77 0.10  7.46 259 1.29e-12
%
%R = 0.42 R2 = 0.18   F = 28.49 on 2 and 259 DF   p-value:  6.53e-12 
%
% 'a'  effect estimates 
%        affect   se    t  df     Prob
%estress   0.17 0.03 5.83 260 1.63e-08
%
% 'b'  effect estimates 
%       withdraw  se    t  df     Prob
%affect     0.77 0.1 7.46 259 1.29e-12
%
% 'ab'  effect estimates 
%        withdraw boot   sd lower upper
%estress     0.13 0.13 0.03  0.07   0.2
%\end{Routput}
%
%\begin{figure}[htbp]
%\begin{center}
%
%\includegraphics{mediate118.pdf}
%\caption{A simple mediation model \citep[p 118] {hayes:13}. The data are from \cite{pollack:12} taken from the \cite{hayes:13} website.  Is the effect of economic stress (estress) on subsequent disengagement from entreprenuerial activities (withdraw) mediated through depressed affect (affect)?}
%\label{default}
%\end{center}
%\end{figure}

\subsection{Multiple mediators}

It is trivial to show the effect of multiple mediators. Do this by adding the second (or third) mediator into the equation.  Use the \fun{Tal\_Or} data set \citep{talor:10} again.  Show the graphical representation in Figure~\ref{fig:2m}.


<<Tal.or>>==

mod5.4 <- mediate(reaction ~ cond  + (import) + (pmi), data = Tal_Or)
print(mod5.4, digits=4)  #to compare with Hayes

@

<<ned131,  echo=FALSE, print=FALSE>>==
png('mediate131.png')
mediate.diagram(mod5.4, digits=3, main="Hayes example 5.3")
dev.off()
@


%\begin{Toutput}
%Call: mediate(y = reaction ~ cond + (import) + (pmi), data = Tal_Or)
%
%The DV (Y) was  reaction . The IV (X) was  cond . The mediating variable(s) =  import pmi . Variable(s)  partialled out were
%
%Total Direct effect(c) of  cond  on  reaction  =  0.4957   S.E. =  0.2775  t direct =  1.786   with probability =  0.07661
%Direct effect (c') of  cond  on  reaction  removing  import pmi  =  0.1034   S.E. =  0.2391  t direct =  0.4324   with probability =  0.6662
%Indirect effect (ab) of  cond  on  reaction  through  import pmi   =  0.3923 
%Mean bootstrapped indirect effect =  0.3964  with standard error =  0.1658  Lower CI =  0.0895    Upper CI =  0.7317
%R2 of model =  0.3251
% To see the longer output, specify short = FALSE in the print statement
%
%
%\end{Toutput}
%\begin{Routput}
% Full output  
%
% Total effect estimates (c) 
%     reaction     se     t     Prob
%cond   0.4957 0.2775 1.786 0.076608
%
%Direct effect estimates     (c') 
%       reaction     se      t       Prob
%cond     0.1034 0.2391 0.4324 6.6622e-01
%import   0.3244 0.0707 4.5857 1.1267e-05
%pmi      0.3965 0.0930 4.2645 4.0383e-05
%
% 'a'  effect estimates 
%         cond     se      t     Prob
%import 0.6268 0.3098 2.0234 0.045235
%pmi    0.4765 0.2357 2.0218 0.045401
%
% 'b'  effect estimates 
%       reaction     se      t       Prob
%import   0.3244 0.0707 4.5857 1.1267e-05
%pmi      0.3965 0.0930 4.2645 4.0383e-05
%
% 'ab'  effect estimates 
%     reaction   boot     sd  lower  upper
%cond   0.3923 0.3965 0.1645 0.0896 0.7392
%> \end{Routput}
%
\begin{figure}[htbp]
\begin{center}
\includegraphics{mediate131.png}
\caption{A  mediation model with two mediators \citep[p 131] {hayes:13}.  The data are  data derived from \cite{talor:10}. The effect of a salience manipulation (cond) on the intention to buy a product (reaction) is mediated through the presumed media influence (pmi) and importance of the message (import).} 
\label{fig:2m}
\end{center}
\end{figure}

\subsection{Serial mediators}  

The example from \cite{hayes:13} for two mediators, where one effects the second, is a bit more complicated and currently can be done by combining two separate analyses. The first is just model 5.4, the second is the effect of cond on pmi mediated by import.  

Combining the two results leads to the output found on \cite[page 153]{hayes:13}.



<<ned131,  echo=FALSE, print=FALSE>>==
png('mediate131.png')
mediate.diagram(mod5.4, digits=3, main="Hayes example 5.3")
dev.off()
@


<<Tal.or54>>==



#model 5.4 + mod5.7 is the two chained mediator model
mod5.7 <- mediate(pmi ~ cond + (import) , data = Tal_Or)
summary(mod5.7, digits=4)
@
%
%\begin{Routput}
%Call: mediate(y = pmi ~ cond + (import), data = Tal_Or)
%
% Total effect estimates (c) 
%        pmi     se      t  df     Prob
%cond 0.4765 0.2357 2.0218 120 0.045419
%
%Direct effect estimates     (c') 
%          pmi     se      t  df      Prob
%cond   0.3536 0.2325 1.5207 120 0.1309600
%import 0.1961 0.0671 2.9228 120 0.0041467
%
%R = 0.3114 R2 = 0.097   F = 6.4428 on 2 and 120 DF   p-value:  0.0021989 
%
% 'a'  effect estimates 
%     import     se      t  df     Prob
%cond 0.6268 0.3098 2.0234 121 0.045235
%
% 'b'  effect estimates 
%          pmi     se      t  df      Prob
%import 0.1961 0.0671 2.9228 120 0.0041467
%
% 'ab'  effect estimates 
%        pmi   boot     sd   lower  upper
%cond 0.1229 0.1226 0.0825 -0.0017 0.3152
%> 
%
%\end{Routput}
%

\subsection{Single mediators, multiple covariates}

The \fun{Pollack} data set \citep{pollack:12} is used as an example of multiple covariates (included in \Rpkg{psychTools} as a correlation matrix).  The raw data are available from the \Rpkg{processR} package as \pfun{estress}.   Confidence in executive decision making (``Entrepeneurial self-effiicacy), gender (sex), and length of time in business (tenure) are used as covariates.  There are two ways of doing this:  enter them as predictors of the criterion or to partial them out.  The first approach estimates their effects, the second just removes them.

<<Pollack>>==
lowerMat(Pollack)
mod6.2 <- mediate(withdrawal ~ economic.stress + self.efficacy + sex + tenure + (depression), 
      data=Pollack, n.obs=262)
summary(mod6.2) 
@

<<Pollackgraph,  echo=FALSE, print=FALSE>>==
png('mediate177.png')
mediate.diagram(mod6.2, digits=3, main = "Simple mediation, 3 covariates")
dev.off()
@

The graphical output  (Figure~\ref{fig:3cov}) looks a bit more complicated than the figure in \cite[p 177]{hayes:13} because I am showing the covariates as causal paths.  
%\begin{Toutput}
%Call: mediate(y = withdraw ~ estress + ese + sex + tenure + (affect), 
%    data = estress)
%
%The DV (Y) was  withdraw . The IV (X) was  estress ese sex tenure . The mediating variable(s) =  affect .
%
%Total effect(c) of  estress  on  withdraw  =  0.02   S.E. =  0.05  t  =  0.35  df=  256   with p =  0.72
%Direct effect (c') of  estress  on  withdraw  removing  affect  =  -0.09   S.E. =  0.05  t  =  -1.78  df=  256   with p =  0.077
%Indirect effect (ab) of  estress  on  withdraw  through  affect   =  0.11 
%Mean bootstrapped indirect effect =  0.11  with standard error =  0.03  Lower CI =  0.06    Upper CI =  0.17
%
%Total effect(c) of  ese  on  withdraw  =  -0.32   S.E. =  0.08  t  =  -3.98  df=  256   with p =  9e-05
%Direct effect (c') of  ese  on  NA  removing  affect  =  -0.21   S.E. =  0.08  t  =  -2.78  df=  256   with p =  0.0059
%Indirect effect (ab) of  ese  on  withdraw  through  affect   =  -0.11 
%Mean bootstrapped indirect effect =  0.11  with standard error =  0.03  Lower CI =  -0.19    Upper CI =  -0.03
%
%Total effect(c) of  sex  on  withdraw  =  0.14   S.E. =  0.16  t  =  0.88  df=  256   with p =  0.38
%Direct effect (c') of  sex  on  NA  removing  affect  =  0.13   S.E. =  0.14  t  =  0.88  df=  256   with p =  0.38
%Indirect effect (ab) of  sex  on  withdraw  through  affect   =  0.01 
%Mean bootstrapped indirect effect =  0.11  with standard error =  0.03  Lower CI =  -0.09    Upper CI =  0.15
%
%Total effect(c) of  tenure  on  withdraw  =  -0.01   S.E. =  0.01  t  =  -0.85  df=  256   with p =  0.4
%Direct effect (c') of  tenure  on  NA  removing  affect  =  0   S.E. =  0.01  t  =  -0.19  df=  256   with p =  0.85
%Indirect effect (ab) of  tenure  on  withdraw  through  affect   =  -0.01 
%Mean bootstrapped indirect effect =  0.11  with standard error =  0.03  Lower CI =  -0.02    Upper CI =  0
%R = 0.45 R2 = 0.21   F = 13.28 on 5 and 256 DF   p-value:  1.63e-11 
%\end{Toutput}
%
%\begin{Routput}
% Full output  
%
%
% Total effect estimates (c) 
%        withdraw   se     t  df     Prob
%estress     0.02 0.05  0.35 256 7.24e-01
%ese        -0.32 0.08 -3.98 256 9.02e-05
%sex         0.14 0.16  0.88 256 3.78e-01
%tenure     -0.01 0.01 -0.85 256 3.97e-01
%
%Direct effect estimates     (c') 
%        withdraw   se     t  df    Prob
%estress    -0.09 0.05 -1.78 256 0.07710
%ese        -0.21 0.08 -2.78 256 0.00589
%sex         0.13 0.14  0.88 256 0.37800
%tenure      0.00 0.01 -0.19 256 0.84600
%
%R = 0.45 R2 = 0.21   F = 13.28 on 5 and 256 DF   p-value:  1.63e-11 
%
% 'a'  effect estimates 
%        affect   se     t  df     Prob
%estress   0.16 0.03  5.36 257 1.84e-07
%ese      -0.15 0.04 -3.49 257 5.70e-04
%sex       0.01 0.09  0.17 257 8.63e-01
%tenure   -0.01 0.01 -1.72 257 8.61e-02
%
% 'b'  effect estimates 
%       withdraw  se    t  df     Prob
%affect     0.71 0.1 6.74 256 1.03e-10
%
% 'ab'  effect estimates 
%        withdraw  boot   sd lower upper
%estress     0.11  0.11 0.03  0.06  0.17
%ese        -0.11 -0.11 0.04 -0.19 -0.03
%sex         0.01  0.02 0.06 -0.09  0.15
%tenure     -0.01 -0.01 0.00 -0.02  0.00
%> 
%\end{Routput}
\begin{figure}[htbp]
\begin{center}
\includegraphics{mediate177.png}
\caption{A  mediation model with three covariates \citep[p 177] {hayes:13}. Compare this to the solution in which they are partialled out.  (Figure~\ref{fig:mod6.2a}).}
\label{fig:3cov}
\end{center}
\end{figure}

\subsection{Single predictor, single criterion, multiple covariates}

An alternative way to display the previous results is to remove the three covariates from the mediation model. Do this by partialling out the covariates.  This is represented in the \pfun{mediate} code by a negative sign  (Figure~\ref{fig:mod6.2a})


<<Pollack>>==
mod6.2a <- mediate(withdrawal ~ economic.stress -self.efficacy - sex - tenure + (depression),
      data=Pollack, n.obs=262)
summary(mod6.2a) 
@

%\begin{Rinput}
%mod6.2a <- mediate(withdraw ~ estress - ese - sex - tenure + (affect), data=estress)
%mod6.2a #give the output
%\end{Rinput}
%\begin{Toutput}
%
%The DV (Y) was  withdraw . The IV (X) was  estress . The mediating variable(s) =  affect . Variable(s)  partialled out were ese sex tenure
%
%Total effect(c) of  estress  on  withdraw  =  0.02   S.E. =  0.05  t  =  0.36  df=  256   with p =  0.72
%Direct effect (c') of  estress  on  withdraw  removing  affect  =  -0.09   S.E. =  0.05  t  =  -1.77  df=  256   with p =  0.078
%Indirect effect (ab) of  estress  on  withdraw  through  affect   =  0.11 
%Mean bootstrapped indirect effect =  0.11  with standard error =  0.03  Lower CI =  0.06    Upper CI =  0.17
%R = 0.39 R2 = 0.15   F = 22.8 on 2 and 256 DF   p-value:  7.71e-10 
%
%\end{Toutput}
%\begin{Routput}
% Full output  
%Total effect estimates (c) 
%        withdraw   se    t  df  Prob
%estress     0.02 0.05 0.36 256 0.722
%
%Direct effect estimates     (c') 
%        withdraw   se     t  df     Prob
%estress    -0.09 0.05 -1.77 256 7.78e-02
%affect      0.71 0.11  6.72 256 1.14e-10
%
%R = 0.39 R2 = 0.15   F = 22.8 on 2 and 256 DF   p-value:  7.71e-10 
%
% 'a'  effect estimates 
%        affect   se    t  df     Prob
%estress   0.16 0.03 5.39 257 1.58e-07
%
% 'b'  effect estimates 
%       withdraw   se    t  df     Prob
%affect     0.71 0.11 6.72 256 1.14e-10
%
% 'ab'  effect estimates 
%        withdraw boot   sd lower upper
%estress     0.11 0.11 0.03  0.06  0.17
%
%
%\end{Routput}
%

<<Pollackgraph,  echo=FALSE, print=FALSE>>==
png('mod62partial.png')
mediate.diagram(mod6.2a, digits=3, main = "Simple mediation, 3 covariates (partialled out)")
dev.off()
@

\begin{figure}[htbp]
\begin{center}
\includegraphics{mod62partial.png}
\caption{Show the mediation model from Figure~\ref{fig:3cov} with the covariates (ese, sex, tenure) removed.}
\label{fig:mod6.2a}
\end{center}
\end{figure}


\subsection{Multiple predictors, single criterion}

It is straightforward to use multiple predictors see \cite[p196]{hayes:13} and in fact  did so in the previous example where the predictors were treated as \emph{covariates}.  \pfun{mediate} also allows for multiple criteria.  

\section{Mediation and moderation}

We already saw how to do moderation in the discussion of \pfun{lmCor}.  Combining the concepts of mediation with moderation is done in \pfun{mediate}. That is, find the linear model of product terms as they are associated with dependent variables and regressed on the mediating variables.

The \fun{Garcia} data set \citep{garcia:10}  can be used for an example of moderation.  (This was taken from \citep{hayes:13} but is used with kind permission of Donna M. Garcia, Michael T. Schmitt, Nyla R. Branscombe, and Naomi Ellemers.) Just as \pfun{setCor} and \fun{lm} will find the interaction term by forming a product, so will \pfun{mediate}.  Notice that by default, \pfun{lmCor} reports zero centered and standardized regressions, \pfun{mediate} reports zero centered but not standardized regressions, and some of the examples from \cite{hayes:13} do  not zero center the data.  Thus, I specify zero=FALSE to get the \cite{hayes:13} results.  

It is important to note that the \fun{protest} data set discussed  here is from the 2013 examples and not the more recent 2018 examples available from \href{http://afhayes.com}{afhayes.com}.  The 2013 data have a dichotomous protest variable, while the 2018 data set has three levels for the protest variable.  The \pfun{Garcia} data set is composed of the 2018 data set with the addition of a dichotomous variable (prot2) to match  the 2013 examples.

We  consider how the interaction of sexism with protest  affects the mediation effect of sexism  \citep[p 362]{hayes:13}, I contrast the \fun{lm}, \pfun{lmCor} and \pfun{mediate} approaches.  For reasons to be discussed in the next section, I do not zero center the variables.  The graphic output is in Figure~\ref{fig:modmed} and the output is below.  For comparison purposes, I show the results from the \fun{lm} as well as \pfun{lmCor} and \pfun{mediate}.


<<interacions>>==
summary(lm(respappr ~ prot2 * sexism,data = Garcia))  #show the lm results for comparison
#show the lmCor analysis
lmCor(respappr ~ prot2* sexism ,data=Garcia,zero=FALSE,main="Moderation",std=FALSE)

#then show the mediate results

modgarcia <-mediate(respappr ~ prot2 * sexism +(sexism),data=Garcia,zero=FALSE,main="Moderated mediation")
summary(modgarcia)

@

<<interacionsplot,  echo=FALSE, print=FALSE>>==
png('moderatedmediation.png')
mediate.diagram(modgarcia, main= "An example of moderated mediation")
dev.off()
@
%lm(formula = respappr ~ prot2 * sexism, data = Garcia)
%
%Residuals:
%    Min      1Q  Median      3Q     Max 
%-3.4984 -0.7540  0.0801  0.8301  3.1853 
%
%Coefficients:
%             Estimate Std. Error t value Pr(>|t|)    
%(Intercept)    6.5667     1.2095   5.429 2.83e-07 ***
%prot2         -2.6866     1.4515  -1.851  0.06654 .  
%sexism        -0.5290     0.2359  -2.243  0.02668 *  
%prot2:sexism   0.8100     0.2819   2.873  0.00478 ** 
%---
%Signif. codes:  0 ?***? 0.001 ?**? 0.01 ?*? 0.05 ?.? 0.1 ? ? 1
%
%Residual standard error: 1.144 on 125 degrees of freedom
%Multiple R-squared:  0.2962,	Adjusted R-squared:  0.2793 
%F-statistic: 17.53 on 3 and 125 DF,  p-value: 1.456e-09
%
%setCor(respappr ~ prot2* sexism ,data=Garcia,zero=FALSE,main="Moderation",std=FALSE)
%Call: setCor(y = respappr ~ prot2 * sexism, data = Garcia, std = FALSE, 
%    main = "Moderation", zero = FALSE)
%
%Multiple Regression from raw data 
%
% DV =  respappr 
%             slope   se     t      p   VIF
%prot2        -2.69 1.45 -1.85 0.0670 44.99
%sexism       -0.53 0.24 -2.24 0.0270  3.34
%prot2*sexism  0.81 0.28  2.87 0.0048 48.14
%
% Multiple Regression
%            R  R2  Ruw R2uw Shrunken R2 SE of R2 overall F df1 df2        p
%respappr 0.54 0.3 0.65 0.43        0.28     0.06     17.53   3 125 1.46e-09
%
%> summary( mediate(respappr ~ prot2 * sexism +(sexism),data=Garcia,zero=FALSE,main="Moderated mediation"))
%Call: mediate(y = respappr ~ prot2 * sexism + (sexism), data = Garcia, 
%    zero = FALSE, main = "Moderated mediation")
%
% Total effect estimates (c) 
%             respappr   se    t  df   Prob
%prot2            0.00 0.84 0.00 125 0.9960
%prot2*sexism     0.28 0.16 1.79 125 0.0756
%
%Direct effect estimates     (c') 
%             respappr   se     t  df    Prob
%prot2           -2.69 1.45 -1.85 125 0.06650
%prot2*sexism     0.81 0.28  2.87 125 0.00478
%
%R = 0.54 R2 = 0.3   F = 17.53 on 3 and 125 DF   p-value:  1.46e-09 
%
% 'a'  effect estimates 
%             sexism   se      t  df     Prob
%prot2         -5.07 0.31 -16.33 126 6.81e-33
%prot2*sexism   1.00 0.06  17.15 126 9.41e-35
%
% 'b'  effect estimates 
%       respappr   se     t  df   Prob
%sexism    -0.53 0.24 -2.24 125 0.0267
%
% 'ab'  effect estimates 
%             respappr  boot   sd lower upper
%prot2            2.68  2.65 1.60 -0.69  5.60
%prot2*sexism    -0.53 -0.52 0.32 -1.11  0.14
%\end{Routput}




\begin{figure}[htbp]
\begin{center}
\includegraphics{moderatedmediation.png}
\caption{Moderated mediation from \citep[p 362]{hayes:13}.  The data are from \cite{garcia:10}.}
\label{fig:modmed}
\end{center}
\end{figure}

\subsection{To center or not to center, that is the question}
We have discussed the difference between zero centering and not zero centering.  Although \cite{hayes:13} seems to prefer not centering, some of his examples are in fact centered.   So, when we examine Table 8.2 and try to replicate the regression, we need to zero center the data.

With the global warming data from \cite{hayes:13}, the default (uncentered) regression does not reproduce his  Table, but zero centering does.  To this in \fun{lm} requires two steps, but we can do this in \pfun{lmCor} with the zero=TRUE or zero=FALSE option.

<<zeri>>==

lm(govact ~ age * negemot + posemot + ideology + sex, data=globalWarm)
# but  zero center and try again
glbwarmc <-data.frame(scale(globalWarm,scale=FALSE))
lm(govact ~ age * negemot + posemot + ideology + sex, data=globalWarm)
mod.glb <- lmCor(govact ~ age * negemot + posemot + ideology + sex, data=globalWarm,zero=FALSE,std=FALSE)
print(mod.glb,digits=6)
mod.glb0 <- lmCor(govact ~ age * negemot + posemot + ideology + sex, data=globalWarm,std=FALSE)
print(mod.glb0,digits=6)
@

%\begin{Routput}
%> lm(govact ~ age * negemot + posemot + ideology + sex, data=glbwarm)
%Call:
%lm(formula = govact ~ age * negemot + posemot + ideology + sex, 
%    data = glbwarm)
%Coefficients:
%(Intercept)          age      negemot      posemot     ideology          sex  age:negemot  
%   5.173849    -0.023879     0.119583    -0.021419    -0.211515    -0.011191     0.006331  
%> # but  zero center and try again
%> glbwarmc <-data.frame(scale(glbwarm,scale=FALSE))
%> lm(govact ~ age * negemot + posemot + ideology + sex, data=glbwarmc)
%
%Call:
%lm(formula = govact ~ age * negemot + posemot + ideology + sex, 
%    data = glbwarmc)
%
%Coefficients:
%(Intercept)          age      negemot      posemot     ideology          sex  age:negemot  
%   0.008979    -0.001354     0.433184    -0.021419    -0.211515    -0.011191     0.006331  
%
%> mod.glb <- setCor(govact ~ age * negemot + posemot + ideology + sex, data=glbwarm,zero=FALSE,std=FALSE)
%>  print(mod.glb,digits=6)
%Call: setCor(y = govact ~ age * negemot + posemot + ideology + sex, 
%    data = glbwarm, std = FALSE, zero = FALSE)
%
%Multiple Regression from raw data 
%
% DV =  govact 
%                slope       se         t           p       VIF
%age         -0.023879 0.005980 -3.992944 7.12038e-05  6.949401
%negemot      0.119583 0.082535  1.448881 1.47759e-01 11.594520
%posemot     -0.021419 0.027904 -0.767597 4.42951e-01  1.028663
%ideology    -0.211515 0.026833 -7.882678 1.02141e-14  1.198910
%sex         -0.011191 0.076003 -0.147240 8.82979e-01  1.052907
%age*negemot  0.006331 0.001543  4.103542 4.48155e-05 16.455422
%
% Multiple Regression
%              R       R2      Ruw     R2uw Shrunken R2 SE of R2 overall F df1 df2 p
%govact 0.633093 0.400806 0.571703 0.326844    0.396357 0.026299  90.07983   6 808 0
%
%> mod.glb0 <- setCor(govact ~ age * negemot + posemot + ideology + sex, data=glbwarm,std=FALSE)
%> print(mod.glb0,digits=6)
%Call: setCor(y = govact ~ age * negemot + posemot + ideology + sex, 
%    data = glbwarm, std = FALSE)
%
%Multiple Regression from raw data 
%
% DV =  govact 
%                slope       se         t           p      VIF
%age         -0.001354 0.002348 -0.576864 5.64192e-01 1.071058
%negemot      0.433184 0.026243 16.506679 0.00000e+00 1.172207
%posemot     -0.021419 0.027904 -0.767597 4.42951e-01 1.028663
%ideology    -0.211515 0.026833 -7.882678 1.02141e-14 1.198910
%sex         -0.011191 0.076003 -0.147240 8.82979e-01 1.052907
%age*negemot  0.006331 0.001543  4.103542 4.48155e-05 1.014744
%
% Multiple Regression
%              R       R2     Ruw     R2uw Shrunken R2 SE of R2 overall F df1 df2 p
%govact 0.633093 0.400806 0.34298 0.117635    0.396357 0.026299  90.07983   6 808 0
%
%\end{Routput}
%

So, when we do the mediated moderation model, we need to use the zero centered option to match the \cite{hayes:13} results from Figure 8.5.

<<izero2>>==
#by default, mediate zero centers before finding the products
 mod.glb <- mediate(govact ~ age * negemot + posemot + ideology + sex + (age), data=globalWarm,zero=TRUE)
summary(mod.glb,digits=4)
@

Compare this output to that of Table 8.2 and Figure 8.5 (p 258 - 259).

%\begin{Routput}
%Call: mediate(y = govact ~ age * negemot + posemot + ideology + sex + 
%    (age), data = glbwarm, zero = TRUE)
%
% Total effect estimates (c) 
%             govact     se       t  df       Prob
%negemot      0.4328 0.0262 16.5043 808 5.9317e-53
%posemot     -0.0220 0.0279 -0.7890 808 4.3036e-01
%ideology    -0.2145 0.0263 -8.1510 808 1.3712e-15
%sex         -0.0173 0.0752 -0.2304 808 8.1783e-01
%age*negemot  0.0063 0.0015  4.1025 808 4.5004e-05
%
%Direct effect estimates     (c') 
%             govact     se       t  df       Prob
%negemot      0.4332 0.0262 16.5067 808 5.7578e-53
%posemot     -0.0214 0.0279 -0.7676 808 4.4295e-01
%ideology    -0.2115 0.0268 -7.8827 808 1.0360e-14
%sex         -0.0112 0.0760 -0.1472 808 8.8298e-01
%age*negemot  0.0063 0.0015  4.1035 808 4.4816e-05
%
%R = 0.6331 R2 = 0.4008   F = 90.0798 on 6 and 808 DF   p-value:  1.8246e-86 
%
% 'a'  effect estimates 
%               age     se      t  df       Prob
%negemot     0.2757 0.3929 0.7017 809 4.8305e-01
%posemot     0.4232 0.4176 1.0135 809 3.1112e-01
%ideology    2.2079 0.3943 5.6002 809 2.9334e-08
%sex         4.5345 1.1269 4.0238 809 6.2643e-05
%age*negemot 0.0031 0.0231 0.1346 809 8.9294e-01
%
% 'b'  effect estimates 
%     govact     se       t  df    Prob
%age -0.0014 0.0023 -0.5769 808 0.56419
%
% 'ab'  effect estimates 
%             govact    boot     sd   lower  upper
%negemot     -0.0004 -0.0004 0.0012 -0.0033 0.0016
%posemot     -0.0006 -0.0005 0.0014 -0.0038 0.0021
%ideology    -0.0030 -0.0029 0.0051 -0.0136 0.0070
%sex         -0.0061 -0.0057 0.0106 -0.0273 0.0150
%age*negemot  0.0000  0.0000 0.0001 -0.0002 0.0002
% \end{Routput}
%

\subsection{Another example of moderated mediation}
The \pfun{Garcia} data set (\pfun{protest} in \cite{hayes:13}) is another example of a moderated analysis.  Use either \pfun{lmCor} or \pfun{mediate} to examine this data set.  The defaults for these two differ, in that \pfun{lmCor} assumes we want to zero center \emph{and} standardize, while \pfun{mediate} defaults to not standardizing but also defaults to zero (mean) centering.  Note that in the next examples we specify we do not want to standardize nor to mean center.

<<garcia2t>>==

psych::describe(Garcia)
lm(liking ~ prot2* sexism + respappr, data=Garcia)
lmCor(liking ~ prot2* sexism + respappr, data = Garcia, zero=FALSE,std=FALSE)
mod7.4 <- mediate(liking ~ prot2 * sexism +respappr, data = Garcia, zero=FALSE)
summary(mod7.4)
@

%\begin{Routput}
% describe(Garcia)
%         vars   n mean   sd median trimmed  mad  min max range  skew kurtosis   se
%protest     1 129 1.03 0.82   1.00    1.04 1.48 0.00   2  2.00 -0.06    -1.52 0.07
%sexism      2 129 5.12 0.78   5.12    5.10 0.74 2.87   7  4.13  0.12    -0.32 0.07
%anger       3 129 2.12 1.66   1.00    1.84 0.00 1.00   7  6.00  1.29     0.26 0.15
%liking      4 129 5.64 1.05   5.83    5.73 0.99 1.00   7  6.00 -1.15     2.48 0.09
%respappr    5 129 4.87 1.35   5.25    4.98 1.11 1.50   7  5.50 -0.75    -0.18 0.12
%prot2       6 129 0.68 0.47   1.00    0.72 0.00 0.00   1  1.00 -0.77    -1.41 0.04
%
%
%
%Call:
%lm(formula = liking ~ prot2 * sexism + respappr, data = Garcia)
%
%Coefficients:
% (Intercept)         prot2        sexism      respappr  prot2:sexism  
%      5.3471       -2.8075       -0.2824        0.3593        0.5426  
%
%> setCor(liking ~ prot2* sexism + respappr, data = Garcia, zero=FALSE,std=FALSE)
%Call: setCor(y = liking ~ prot2 * sexism + respappr, data = Garcia, 
%    std = FALSE, zero = FALSE)
%
%Multiple Regression from raw data 
%
% DV =  liking 
%             slope   se     t       p   VIF
%prot2        -2.81 1.16 -2.42 1.7e-02 46.22
%sexism       -0.28 0.19 -1.49 1.4e-01  3.47
%respappr      0.36 0.07  5.09 1.3e-06  1.42
%prot2*sexism  0.54 0.23  2.36 2.0e-02 51.32
%
% Multiple Regression
%          R   R2  Ruw R2uw Shrunken R2 SE of R2 overall F df1 df2        p
%liking 0.53 0.28 0.39 0.15        0.26     0.06     12.26   4 124 1.99e-08
%> mod7.4m <- mediate(liking ~ protest * sexism, data = protest, zero=FALSE)
%> mod7.4m
%Call: mediate(y = liking ~ prot2 * sexism + respappr, data = Garcia, 
%    zero = FALSE)
%
%The DV (Y) was  liking . The IV (X) was  prot2 sexism respappr prot2*sexism . The mediating variable(s) =  .
% DV =  liking 
%             slope   se     t       p
%prot2        -2.81 1.16 -2.42 1.7e-02
%sexism       -0.28 0.19 -1.49 1.4e-01
%respappr      0.36 0.07  5.09 1.3e-06
%prot2*sexism  0.54 0.23  2.36 2.0e-02
%
%With R2 =  0.28
%R = 0.53 R2 = 0.28   F = 12.26 on 4 and 124 DF   p-value:  1.99e-08 
%\end{Routput}

<<modertionplot,  echo=FALSE, print=FALSE>>==
png('mod74.png')
mediate.diagram(mod7.4, main= "Another example of moderated mediation")
dev.off()
@
\begin{figure}[htbp]
\begin{center}
\includegraphics{mod74.png}
\caption{A simple moderated regression analysis of the \fun{protest} data set.  The data were not zero centered. This shows the strength of the three regressions.  Figure~\ref{fig:garcia}  shows the actual data and the three regression lines. }
\label{fig:moderation}
\end{center}
\end{figure}


\subsection{Graphic Displays of Interactions}

In order to graphically display interactions, particularly if one of the variable is categorical, pllot separate regression lines for each value of the categorical variable.  Do this for the \pfun{Garcia} data set to show the interaction of protest with sexism. (see Figure~\ref{fig:garcia}).  This is just an example of how to use Core-R to do graphics and is not a feature of \Rpkg{psych}.

<<modertionplot,  echo=TRUE, print=FALSE>>==
png('garciainteraction.png')
plot(respappr ~ sexism, pch = 23- protest, bg = c("black","red", "blue")[protest], 
data=Garcia, main = "Response to sexism varies as type of protest")
by(Garcia,Garcia$protest, function(x) abline(lm(respappr ~ sexism,
   data =x),lty=c("solid","dashed","dotted")[x$protest+1])) 
text(6.5,3.5,"No protest")
text(3,3.9,"Individual")
text(3,5.2,"Collective")
dev.off()

@
\begin{figure}[htbp]
\begin{center}
\includegraphics{garciainteraction.png}
\caption{Showing the interaction between type of protest and sexism from the  \fun{Garcia} data set.  The strength of the regression effects is shown in Fig~\ref{fig:moderation}.}
\label{fig:garcia}
\end{center}
\end{figure}


\section{Partial Correlations}
Although not strickly speaking part of mediation or moderation, the use of \emph{partial correlations} can be addressed here.
s\subsection{Partial some variables from the rest of the variables}

Given a set of X variables and a set of Y variables, we can control for an additional set of Z variables when we find the correlations between X and Y.  This is effectively what happens when we want to add covariates into a model.  We see this when we compare the regression model for government action as a function of the iteraction of ideology and age with some covariates, or when we partial them out first.



<<oartial>>==

 #first,  the more complicated model
 mod.glb <- lmCor(govact ~ age * negemot + posemot + ideology + sex, 
                   data=globalWarm,std=FALSE)
print(mod.glb,digits=3)

# compare this to the partialled model

mod.glb.partialled <- lmCor(govact ~ age * negemot - posemot - ideology - sex,data = globalWarm)
 
@

%
%\begin{Routput}
%  print(mod.glb,digits=3)
%Call: setCor(y = govact ~ age * negemot + posemot + ideology + sex, 
%    data = glbwarm, std = FALSE)
%
%Multiple Regression from raw data 
%
% DV =  govact 
%             slope    se      t        p   VIF
%age         -0.001 0.002 -0.577 5.64e-01 1.071
%negemot      0.433 0.026 16.507 0.00e+00 1.172
%posemot     -0.021 0.028 -0.768 4.43e-01 1.029
%ideology    -0.212 0.027 -7.883 1.02e-14 1.199
%sex         -0.011 0.076 -0.147 8.83e-01 1.053
%age*negemot  0.006 0.002  4.104 4.48e-05 1.015
%
% Multiple Regression
%           R    R2   Ruw  R2uw Shrunken R2 SE of R2 overall F df1 df2 p
%govact 0.633 0.401 0.343 0.118       0.396    0.026     90.08   6 808 0
%> 
%mod.glb.partialled <- setCor(govact ~ age * negemot - posemot - ideology - sex,
%+                     data=glbwarm,std=FALSE)
%
%mod.glb.partialled
%Call: setCor(y = govact ~ age * negemot - posemot - ideology - sex, 
%    data = glbwarm)
%
%Multiple Regression from raw data 
%
% DV =  govact 
%            slope   se     t       p  VIF
%age         -0.02 0.03 -0.54 0.59000 1.00
%negemot      0.49 0.03 16.19 0.00000 1.01
%age*negemot  0.11 0.03  3.75 0.00019 1.01
%
% Multiple Regression
%          R   R2  Ruw R2uw Shrunken R2 SE of R2 overall F df1 df2 p
%govact 0.52 0.27 0.33 0.11        0.27     0.03     100.5   3 811 0
%> 
%\end{Routput}


Note how the beta weights for the age, negemot and interaction terms are identical.

\subsection{Partial everything from everything}
Sometimes we want to examine just  the independent effects of all our variables.  That is to say, we want to partial all the variables from all the other variables.  I do this with the \pfun{partial.r} function.  To show the results, I compare the partialed rs to the original rs.   I  show the lower off diagonal matrix using \pfun{lowerMat}.  Then to compare the partial matrix to the original matrix, I form the square matrix where the lower off diagonal is the original matrix and the upper off  diagonal is the partial matrix.


<<partial.all>>==

upper <-partial.r(globalWarm) 
lowerMat(upper)  #show it
lower <- lowerCor(globalWarm)
lowup <- lowerUpper(lower,upper)

@

%\begin{Routput}
%upper <-partial.r(glbwarm) 
%> lowerMat(upper)  #show it
%         govct posmt negmt idlgy age   sex   prtyd
%govact    1.00                                    
%posemot  -0.03  1.00                              
%negemot   0.50  0.13  1.00                        
%ideology -0.19  0.00 -0.07  1.00                  
%age      -0.02  0.04  0.03  0.14  1.00            
%sex       0.00  0.08 -0.07  0.04  0.14  1.00      
%partyid  -0.08 -0.01 -0.09  0.53  0.03  0.02  1.00
%> lower <- lowerCor(glbwarm)
%         govct posmt negmt idlgy age   sex   prtyd
%govact    1.00                                    
%posemot   0.04  1.00                              
%negemot   0.58  0.13  1.00                        
%ideology -0.42 -0.03 -0.35  1.00                  
%age      -0.10  0.04 -0.06  0.21  1.00            
%sex      -0.10  0.07 -0.12  0.13  0.17  1.00      
%partyid  -0.36 -0.04 -0.32  0.62  0.15  0.11  1.00
%
%\end{Routput}

<<partial.plot,  echo=FALSE, print=FALSE>>==
png('partials.png')
psych::corPlot(lowup,numbers = TRUE)
dev.off()
@

\begin{figure}[htbp]
\begin{center}
\includegraphics[width=9cm]{partials.png}

\caption{Correlations (below diagonal) and partial correlations (above the diagonal) }
\label{default}
\end{center}
\end{figure}

\section{Related packages}

\pfun{mediate} and \pfun{lmCor} are just two functions in the \Rpkg{psych} package.  There are several additional packages available in \R{} to do mediation. The  \Rpkg{mediation} package   \citep{mediation} seems the most powerful, in that is tailor made for mediation.  \Rpkg{MBESS} \citep{MBESS} has a mediation function.   Steven Short has a nice tutorial on mediation analysis available for download  \href{http://docs.wixstatic.com/ugd/bb3887\_73181065d7c744c4a0925844302cf813.pdf}{that discusses how to use R for mediation.}  And, of course, the \Rpkg{lavaan} package \citep{lavaan} is the recommended package to do SEM and path models.
\newpage

\section{Development version and a users guide} 

The \Rpkg{psych} package is available from the CRAN repository.  However, the most recent development version of the \Rpkg{psych} package is available as a source file at the repository maintained at \href{ href="http://personality-project.org/r"}{\url{http://personality-project.org/r}}.  That version will have removed the most recently discovered bugs (but perhaps introduced other, yet to be discovered ones). To install this development version, either for PCs or Macs,  


\begin{Rinput}
install.packages("psych", repos =  "http://personality-project.org/r", type = "source")

\end{Rinput}
After doing this, it is important to restart \R{} to get the new package.

Although the individual help pages for the \Rpkg{psych} package are available as part of \R{} and may be accessed directly (e.g. ?psych) , the full manual for the \pfun{psych} package is also available as a pdf at  \url{http://personality-project.org/r/psych_manual.pdf}
 %psych\_manual.pdf.

News and a history of changes are available in the NEWS and CHANGES files in the source files. To view the most recent news, 

\begin{Schunk}
\begin{Sinput}
> news(Version >= "2.3.12",package="psych")
\end{Sinput}
\end{Schunk}



\section{Psychometric Theory}
The \Rpkg{psych} package has been developed to help psychologists (and other quantitative scientists) do basic research.  Many of the functions were developed to supplement a book (\url{http://personality-project.org/r/book} An introduction to Psychometric Theory with Applications in \R{} \citep{revelle:intro}  More information about the use of some of the functions may be found in the book . 


For more extensive discussion of the use of \Rpkg{psych} in particular and \R{} in general, consult  \url{http://personality-project.org/r/r.guide.html} A short guide to R.


\section{SessionInfo}
This document was prepared using the following settings.

\begin{tiny}
<<sessionInfo>>==

sessionInfo()
@
\end{tiny} 
\
\newpage
%\bibliography{../../../all} 
\begin{thebibliography}{}

\bibitem[\protect\astroncite{Cohen}{1982}]{cohen:82}
Cohen, J. (1982).
\newblock Set correlation as a general mulitivariate data-analytic method.
\newblock {\em Multivariate Behavioral Research}, 17(3):301--341.

\bibitem[\protect\astroncite{Cohen et~al.}{2003}]{cohen:03}
Cohen, J., Cohen, P., West, S.~G., and Aiken, L.~S. (2003).
\newblock {\em Applied multiple regression/correlation analysis for the
  behavioral sciences}.
\newblock L. Erlbaum Associates, Mahwah, N.J., 3rd ed edition.

\bibitem[\protect\astroncite{Dawes}{1979}]{dawes:79}
Dawes, R.~M. (1979).
\newblock The robust beauty of improper linear models in decision making.
\newblock {\em American Psychologist}, 34(7):571--582.

\bibitem[\protect\astroncite{Garcia et~al.}{2010}]{garcia:10}
Garcia, D.~M., Schmitt, M.~T., Branscombe, N.~R., and Ellemers, N. (2010).
\newblock Women's reactions to ingroup members who protest discriminatory
  treatment: The importance of beliefs about inequality and response
  appropriateness.
\newblock {\em European Journal of Social Psychology}, 40(5):733--745.

\bibitem[\protect\astroncite{Hayes}{2013}]{hayes:13}
Hayes, A.~F. (2013).
\newblock {\em Introduction to mediation, moderation, and conditional process
  analysis: A regression-based approach}.
\newblock Guilford Press, New York.

\bibitem[\protect\astroncite{Hotelling}{1936}]{hotelling:36}
Hotelling, H. (1936).
\newblock Relations between two sets of variates.
\newblock {\em Biometrika}, 28(3/4):321--377.

\bibitem[\protect\astroncite{Kelley}{2017}]{MBESS}
Kelley, K. (2017).
\newblock {\em {MBESS: The MBESS R} Package}.
\newblock R package version 4.4.1.

\bibitem[\protect\astroncite{Pollack et~al.}{2012}]{pollack:12}
Pollack, J.~M., Vanepps, E.~M., and Hayes, A.~F. (2012).
\newblock The moderating role of social ties on entrepreneurs' depressed affect
  and withdrawal intentions in response to economic stress.
\newblock {\em Journal of Organizational Behavior}, 33(6):789--810.

\bibitem[\protect\astroncite{Preacher}{2015}]{preacher:15}
Preacher, K.~J. (2015).
\newblock Advances in mediation analysis: A survey and synthesis of new
  developments.
\newblock {\em Annual Review of Psychology}, 66:825--852.

\bibitem[\protect\astroncite{Preacher and Hayes}{2004}]{preacher:04}
Preacher, K.~J. and Hayes, A.~F. (2004).
\newblock {SPSS and SAS} procedures for estimating indirect effects in simple
  mediation models.
\newblock {\em Behavior Research Methods, Instruments, \& Computers},
  36(4):717--731.

\bibitem[\protect\astroncite{Preacher et~al.}{2007}]{preacher:07}
Preacher, K.~J., Rucker, D.~D., and Hayes, A.~F. (2007).
\newblock Addressing moderated mediation hypotheses: Theory, methods, and
  prescriptions.
\newblock {\em Multivariate behavioral research}, 42(1):185--227.

\bibitem[\protect\astroncite{{R Core Team}}{2025}]{R}
{R Core Team} (2025).
\newblock {\em R: A Language and Environment for Statistical Computing}.
\newblock R Foundation for Statistical Computing, Vienna, Austria.

\bibitem[\protect\astroncite{Revelle}{2023}]{psych}
Revelle, W. (2023).
\newblock {\em
  \href{https://cran.r-project.org/web/packages/psych/index.html}{psych}:
  Procedures for Personality and Psychological Research}.
\newblock Northwestern University, Evanston,
  https://CRAN.r-project.org/package=psych.
\newblock R package version 2.3.6

\bibitem[\protect\astroncite{Revelle}{prep}]{revelle:intro}
Revelle, W. ({in prep}).
\newblock {\em An introduction to psychometric theory with applications in
  {R}}.
\newblock Springer.

\bibitem[\protect\astroncite{Rosseel}{2012}]{lavaan}
Rosseel, Y. (2012).
\newblock {lavaan}: An {R} package for structural equation modeling.
\newblock {\em Journal of Statistical Software}, 48(2):1--36.

\bibitem[\protect\astroncite{Tal-Or et~al.}{2010}]{talor:10}
Tal-Or, N., Cohen, J., Tsfati, Y., and Gunther, A.~C. (2010).
\newblock Testing causal direction in the influence of presumed media
  influence.
\newblock {\em Communication Research}, 37(6):801--824.

\bibitem[\protect\astroncite{Tingley et~al.}{2014}]{mediation}
Tingley, D., Yamamoto, T., Hirose, K., Keele, L., and Imai, K. (2014).
\newblock {mediation}: {R} package for causal mediation analysis.
\newblock {\em Journal of Statistical Software}, 59(5):1--38.

\end{thebibliography}
\begin{thebibliography}{}

\bibitem[\protect\astroncite{Cohen}{1982}]{cohen:82}
Cohen, J. (1982).
\newblock Set correlation as a general mulitivariate data-analytic method.
\newblock {\em Multivariate Behavioral Research}, 17(3):301--341.

\bibitem[\protect\astroncite{Cohen et~al.}{2003}]{cohen:03}
Cohen, J., Cohen, P., West, S.~G., and Aiken, L.~S. (2003).
\newblock {\em Applied multiple regression/correlation analysis for the
  behavioral sciences}.
\newblock L. Erlbaum Associates, Mahwah, N.J., 3rd ed edition.

\bibitem[\protect\astroncite{Dawes}{1979}]{dawes:79}
Dawes, R.~M. (1979).
\newblock The robust beauty of improper linear models in decision making.
\newblock {\em American Psychologist}, 34(7):571--582.

\bibitem[\protect\astroncite{Garcia et~al.}{2010}]{garcia:10}
Garcia, D.~M., Schmitt, M.~T., Branscombe, N.~R., and Ellemers, N. (2010).
\newblock Women's reactions to ingroup members who protest discriminatory
  treatment: The importance of beliefs about inequality and response
  appropriateness.
\newblock {\em European Journal of Social Psychology}, 40(5):733--745.

\bibitem[\protect\astroncite{Hayes}{2013}]{hayes:13}
Hayes, A.~F. (2013).
\newblock {\em Introduction to mediation, moderation, and conditional process
  analysis: A regression-based approach}.
\newblock Guilford Press, New York.

\bibitem[\protect\astroncite{Hotelling}{1936}]{hotelling:36}
Hotelling, H. (1936).
\newblock Relations between two sets of variates.
\newblock {\em Biometrika}, 28(3/4):321--377.

\bibitem[\protect\astroncite{Kelley}{2017}]{MBESS}
Kelley, K. (2017).
\newblock {\em {MBESS: The MBESS R} Package}.
\newblock R package version 4.4.1.

\bibitem[\protect\astroncite{Pollack et~al.}{2012}]{pollack:12}
Pollack, J.~M., Vanepps, E.~M., and Hayes, A.~F. (2012).
\newblock The moderating role of social ties on entrepreneurs' depressed affect
  and withdrawal intentions in response to economic stress.
\newblock {\em Journal of Organizational Behavior}, 33(6):789--810.

\bibitem[\protect\astroncite{Preacher}{2015}]{preacher:15}
Preacher, K.~J. (2015).
\newblock Advances in mediation analysis: A survey and synthesis of new
  developments.
\newblock {\em Annual Review of Psychology}, 66:825--852.

\bibitem[\protect\astroncite{Preacher and Hayes}{2004}]{preacher:04}
Preacher, K.~J. and Hayes, A.~F. (2004).
\newblock {SPSS and SAS} procedures for estimating indirect effects in simple
  mediation models.
\newblock {\em Behavior Research Methods, Instruments, \& Computers},
  36(4):717--731.

\bibitem[\protect\astroncite{Preacher et~al.}{2007}]{preacher:07}
Preacher, K.~J., Rucker, D.~D., and Hayes, A.~F. (2007).
\newblock Addressing moderated mediation hypotheses: Theory, methods, and
  prescriptions.
\newblock {\em Multivariate behavioral research}, 42(1):185--227.

\bibitem[\protect\astroncite{{R Core Team}}{2023}]{R}
{R Core Team} (2023).
\newblock {\em R: A Language and Environment for Statistical Computing}.
\newblock R Foundation for Statistical Computing, Vienna, Austria.


\bibitem[\protect\astroncite{{Moon}}{2020}]{processR}
{Keon-Woong Moon} (2020).
\newblock {\em processR: Implementation of the 'PROCESS' Macro}.
\newblock https://CRAN.R-project.org/package=processR

\bibitem[\protect\astroncite{Revelle}{2025}]{psych}
Revelle, W. (2025).
\newblock {\em
  \href{https://cran.r-project.org/web/packages/psych/index.html}{psych}:
  Procedures for Personality and Psychological Research}.
\newblock Northwestern University, Evanston,
  https://CRAN.r-project.org/package=psych.
\newblock R package version 2.4.3

\bibitem[\protect\astroncite{Revelle}{prep}]{revelle:intro}
Revelle, W. ({in prep}).
\newblock {\em An introduction to psychometric theory with applications in
  {R}}.
\newblock Springer.

\bibitem[\protect\astroncite{Rosseel}{2012}]{lavaan}
Rosseel, Y. (2012).
\newblock {lavaan}: An {R} package for structural equation modeling.
\newblock {\em Journal of Statistical Software}, 48(2):1--36.

\bibitem[\protect\astroncite{Tabachnick and Fidell}{2001}]{Tabachnick:01}
Tabacnik, B.G and Fidell, L.S. (2001)
\newblock Using multivariate statistics.
\newblock  Allyn and Bacon.

\bibitem[\protect\astroncite{Tal-Or et~al.}{2010}]{talor:10}
Tal-Or, N., Cohen, J., Tsfati, Y., and Gunther, A.~C. (2010).
\newblock Testing causal direction in the influence of presumed media
  influence.
\newblock {\em Communication Research}, 37(6):801--824.

\bibitem[\protect\astroncite{Tingley et~al.}{2014}]{mediation}
Tingley, D., Yamamoto, T., Hirose, K., Keele, L., and Imai, K. (2014).
\newblock {mediation}: {R} package for causal mediation analysis.
\newblock {\em Journal of Statistical Software}, 59(5):1--38.

\end{thebibliography}


%\printindex
\end{document}  