# import data
library(readr)
d <- read_csv("/Users/melissalagunas/Desktop/Lab/Contextualizing\ Stigma\ and\ Trauma/LatineData_Subscales.csv")
## New names:
## Rows: 259 Columns: 16
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," dbl
## (16): ...1, SSRPH, SSOSH, MHSAS, PR_PF, PR_A, PR_D, PR_SR, PR_PI, ANG, C...
## ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## • `` -> `...1`
# import data
library(readr)
dat <- read_csv("/Users/melissalagunas/Desktop/Lab/Contextualizing\ Stigma\ and\ Trauma/LatineData2.csv")
## New names:
## Rows: 259 Columns: 151
## ── Column specification
## ──────────────────────────────────────────────────────── Delimiter: "," chr
## (4): AHELP, GEN_8_TEXT, ETH_7_TEXT, BORN_1 dbl (146): ...1, Progress,
## Duration..in.seconds., Consent, SSRPH_1, SSRPH_2,... lgl (1): EDU_11_TEXT
## ℹ Use `spec()` to retrieve the full column specification for this data. ℹ
## Specify the column types or set `show_col_types = FALSE` to quiet this message.
## • `` -> `...1`
# remove NA variables
d <- na.omit(d)
#data set with only variables of interest
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
d <- data.frame(d$PHFS, d$MHSAS, d$SSOSH, d$SSRPH)
d <- rename(d, familism = d.PHFS, help_seeking_attitudes = d.MHSAS, self_stigma = d.SSOSH, public_stigma = d.SSRPH)
#loading packages
library(lavaan)
## This is lavaan 0.6-16
## lavaan is FREE software! Please report any bugs.
library(semPlot)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ stringr   1.5.0
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(psych)
## 
## Attaching package: 'psych'
## 
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
## 
## The following object is masked from 'package:lavaan':
## 
##     cor2cov
library(jtools)
library(interactions)
library(ggplot2)
library(tidySEM)
## Loading required package: OpenMx
## OpenMx may run faster if it is compiled to take advantage of multiple cores.
## 
## Attaching package: 'OpenMx'
## 
## The following object is masked from 'package:psych':
## 
##     tr
## 
## Registered S3 method overwritten by 'tidySEM':
##   method          from  
##   predict.MxModel OpenMx
## 
## Attaching package: 'tidySEM'
## 
## The following object is masked from 'package:jtools':
## 
##     get_data
# Correlation Analysis 

table <- apaTables::apa.cor.table(d, table.number = 1, show.sig.stars = TRUE,
    landscape = TRUE, filename = "table.doc")
## Registered S3 methods overwritten by 'broom':
##   method            from  
##   tidy.glht         jtools
##   tidy.summary.glht jtools
print(table)
## 
## 
## Table 1 
## 
## Means, standard deviations, and correlations with confidence intervals
##  
## 
##   Variable                  M    SD   1            2            3         
##   1. familism               3.68 0.99                                     
##                                                                           
##   2. help_seeking_attitudes 5.54 1.16 .21**                               
##                                       [.09, .32]                          
##                                                                           
##   3. self_stigma            2.32 0.83 -.18**       -.55**                 
##                                       [-.30, -.06] [-.63, -.46]           
##                                                                           
##   4. public_stigma          2.22 0.67 -.12         -.40**       .56**     
##                                       [-.24, .00]  [-.50, -.29] [.46, .63]
##                                                                           
## 
## Note. M and SD are used to represent mean and standard deviation, respectively.
## Values in square brackets indicate the 95% confidence interval.
## The confidence interval is a plausible range of population correlations 
## that could have caused the sample correlation (Cumming, 2014).
##  * indicates p < .05. ** indicates p < .01.
## 
psych::pairs.panels(d)

# Checking the table of means, standard deviations, and correlations 
table <- apaTables::apa.cor.table(d, table.number = 1, show.sig.stars = TRUE,
    landscape = TRUE, filename = "Lewis_Corr.doc")
print(table)
## 
## 
## Table 1 
## 
## Means, standard deviations, and correlations with confidence intervals
##  
## 
##   Variable                  M    SD   1            2            3         
##   1. familism               3.68 0.99                                     
##                                                                           
##   2. help_seeking_attitudes 5.54 1.16 .21**                               
##                                       [.09, .32]                          
##                                                                           
##   3. self_stigma            2.32 0.83 -.18**       -.55**                 
##                                       [-.30, -.06] [-.63, -.46]           
##                                                                           
##   4. public_stigma          2.22 0.67 -.12         -.40**       .56**     
##                                       [-.24, .00]  [-.50, -.29] [.46, .63]
##                                                                           
## 
## Note. M and SD are used to represent mean and standard deviation, respectively.
## Values in square brackets indicate the 95% confidence interval.
## The confidence interval is a plausible range of population correlations 
## that could have caused the sample correlation (Cumming, 2014).
##  * indicates p < .05. ** indicates p < .01.
## 
# quick peak at data
psych::describe(d)
##                        vars   n mean   sd median trimmed  mad min max range
## familism                  1 257 3.68 0.99   3.80    3.77 0.89   1 5.0   4.0
## help_seeking_attitudes    2 257 5.54 1.16   5.78    5.66 0.99   1 7.0   6.0
## self_stigma               3 257 2.32 0.83   2.10    2.25 0.74   1 4.9   3.9
## public_stigma             4 257 2.22 0.67   2.20    2.21 0.59   1 4.0   3.0
##                         skew kurtosis   se
## familism               -0.76     0.13 0.06
## help_seeking_attitudes -1.13     1.45 0.07
## self_stigma             0.73    -0.05 0.05
## public_stigma           0.19    -0.05 0.04

Working the Moderated Mediation

Piecewise assemly of the moderated mediation

Analysis 1: A simple moderation

# Y = self-stigma; X = public stigma; W = familism

Mod_a_path <- lm(self_stigma ~ public_stigma * familism, data = d)
jtools::summ(Mod_a_path, digits = 3)
## MODEL INFO:
## Observations: 257
## Dependent Variable: self_stigma
## Type: OLS linear regression 
## 
## MODEL FIT:
## F(3,253) = 43.036, p = 0.000
## R² = 0.338
## Adj. R² = 0.330 
## 
## Standard errors: OLS
## --------------------------------------------------------------
##                                  Est.    S.E.   t val.       p
## ---------------------------- -------- ------- -------- -------
## (Intercept)                    -0.088   0.556   -0.159   0.874
## public_stigma                   1.227   0.230    5.343   0.000
## familism                        0.243   0.143    1.698   0.091
## public_stigma:familism         -0.149   0.060   -2.496   0.013
## --------------------------------------------------------------
#graph interaction
interactions::interact_plot(Mod_a_path, pred = public_stigma, modx = familism) +
    ylim(1, 10)

#probing the interaction with simple slopes
interactions::sim_slopes(Mod_a_path, pred = public_stigma, modx = familism)
## JOHNSON-NEYMAN INTERVAL 
## 
## When familism is OUTSIDE the interval [6.12, 25.27], the slope of
## public_stigma is p < .05.
## 
## Note: The range of observed values of familism is [1.00, 5.00]
## 
## SIMPLE SLOPES ANALYSIS 
## 
## Slope of public_stigma when familism = 2.686265 (- 1 SD): 
## 
##   Est.   S.E.   t val.      p
## ------ ------ -------- ------
##   0.83   0.09     9.41   0.00
## 
## Slope of public_stigma when familism = 3.676265 (Mean): 
## 
##   Est.   S.E.   t val.      p
## ------ ------ -------- ------
##   0.68   0.06    10.53   0.00
## 
## Slope of public_stigma when familism = 4.666264 (+ 1 SD): 
## 
##   Est.   S.E.   t val.      p
## ------ ------ -------- ------
##   0.53   0.09     6.08   0.00
  # The Johnson-Neyman is a floodlight approach and provides an indication of the places in the distribution of W (moderator) that X has an effect on Y that is different than zero. The analysis of simple slopes approach is thought of as a spotlight approach because probes the distribution at specific values (often the M +/- 1SD).

In this model that is, overall, statistically significant, we account for about 33% of the variance in self-stigma. Looking at these results we can see that there is a statistically significant main effect of public stigma on self-stigma as well as a statistically significant interaction effect (public stigma:familism [XM])

Analysis 2: Another simple moderation

# Y = help-seeking attitudes; X = self-stigma; W = familism

Mod_b_path <- lm(help_seeking_attitudes ~ self_stigma * familism, data = d)
jtools::summ(Mod_b_path, digits = 3)
## MODEL INFO:
## Observations: 257
## Dependent Variable: help_seeking_attitudes
## Type: OLS linear regression 
## 
## MODEL FIT:
## F(3,253) = 38.379, p = 0.000
## R² = 0.313
## Adj. R² = 0.305 
## 
## Standard errors: OLS
## ------------------------------------------------------------
##                                Est.    S.E.   t val.       p
## -------------------------- -------- ------- -------- -------
## (Intercept)                   6.965   0.628   11.088   0.000
## self_stigma                  -0.829   0.237   -3.504   0.001
## familism                      0.074   0.161    0.463   0.644
## self_stigma:familism          0.026   0.062    0.418   0.676
## ------------------------------------------------------------
#graph interaction
interactions::interact_plot(Mod_b_path, pred = self_stigma, modx = familism) +
    ylim(1, 10)

#probing the interaction with simple slopes
interactions::sim_slopes(Mod_b_path, pred = self_stigma, modx = familism)
## JOHNSON-NEYMAN INTERVAL 
## 
## When familism is INSIDE the interval [-3.88, 8.42], the slope of
## self_stigma is p < .05.
## 
## Note: The range of observed values of familism is [1.00, 5.00]
## 
## SIMPLE SLOPES ANALYSIS 
## 
## Slope of self_stigma when familism = 2.686265 (- 1 SD): 
## 
##    Est.   S.E.   t val.      p
## ------- ------ -------- ------
##   -0.76   0.09    -8.11   0.00
## 
## Slope of self_stigma when familism = 3.676265 (Mean): 
## 
##    Est.   S.E.   t val.      p
## ------- ------ -------- ------
##   -0.73   0.07    -9.89   0.00
## 
## Slope of self_stigma when familism = 4.666264 (+ 1 SD): 
## 
##    Est.   S.E.   t val.      p
## ------- ------ -------- ------
##   -0.71   0.10    -7.13   0.00
  # The Johnson-Neyman is a floodlight approach and provides an indication of the places in the distribution of W (moderator) that X has an effect on Y that is different than zero. The analysis of simple slopes approach is thought of as a spotlight approach because probes the distribution at specific values (often the M +/- 1SD).

Looking at these results we can see that the predictors account for 31.3% of variance in help-seeking attitudes. Only the independent variable (X), self-stigma is a significant predictor. Neither the moderator (familism), nor its interaction with self-stigma (self_stigma:familism [XW]) are signficant.

Analysis 3: A simple mediation

# Y = help-seeking attitudes; X = public_stigma; M = self_stigma
LMedModel <- "
          help_seeking_attitudes ~ b*self_stigma + c_p*public_stigma 
          self_stigma ~a*public_stigma
          
          #intercepts
          self_stigma ~ self_stigma.mean*1
          help_seeking_attitudes ~ help_seeking_attitudes.mean*1
          
          indirect :=  a*b
          direct  := c_p
          total_c  := c_p + (a*b)
          "
set.seed(230925)  #required for reproducible results because lavaan introduces randomness into the calculations
LMed_fit <- lavaan::sem(LMedModel, data = d, se = "bootstrap", missing = "fiml")
LMed_Sum <- lavaan::summary(LMed_fit, standardized = T, rsq = T, ci = TRUE)
LMed_ParEsts <- lavaan::parameterEstimates(LMed_fit, boot.ci.type = "bca.simple",
    standardized = TRUE)
LMed_Sum
## lavaan 0.6.16 ended normally after 1 iteration
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         7
## 
##   Number of observations                           257
##   Number of missing patterns                         1
## 
## Model Test User Model:
##                                                       
##   Test statistic                                 0.000
##   Degrees of freedom                                 0
## 
## Parameter Estimates:
## 
##   Standard errors                            Bootstrap
##   Number of requested bootstrap draws             1000
##   Number of successful bootstrap draws            1000
## 
## Regressions:
##                            Estimate  Std.Err  z-value  P(>|z|) ci.lower
##   help_seeking_attitudes ~                                             
##     slf_stgm   (b)           -0.659    0.101   -6.530    0.000   -0.864
##     pblc_stg (c_p)           -0.236    0.123   -1.921    0.055   -0.484
##   self_stigma ~                                                        
##     pblc_stg   (a)            0.694    0.075    9.219    0.000    0.545
##  ci.upper   Std.lv  Std.all
##                            
##    -0.463   -0.659   -0.472
##    -0.002   -0.236   -0.135
##                            
##     0.840    0.694    0.555
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|) ci.lower ci.upper
##    .slf_stg (sl_.)    0.780    0.154    5.080    0.000    0.480    1.072
##    .hlp_sk_ (h__.)    7.587    0.225   33.737    0.000    7.145    8.021
##    Std.lv  Std.all
##     0.780    0.938
##     7.587    6.537
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|) ci.lower ci.upper
##    .hlp_skng_tttds    0.927    0.125    7.397    0.000    0.679    1.158
##    .self_stigma       0.478    0.042   11.483    0.000    0.396    0.559
##    Std.lv  Std.all
##     0.927    0.688
##     0.478    0.692
## 
## R-Square:
##                    Estimate
##     hlp_skng_tttds    0.312
##     self_stigma       0.308
## 
## Defined Parameters:
##                    Estimate  Std.Err  z-value  P(>|z|) ci.lower ci.upper
##     indirect         -0.457    0.090   -5.069    0.000   -0.648   -0.289
##     direct           -0.236    0.123   -1.920    0.055   -0.484   -0.002
##     total_c          -0.693    0.106   -6.528    0.000   -0.888   -0.462
##    Std.lv  Std.all
##    -0.457   -0.262
##    -0.236   -0.135
##    -0.693   -0.397

The a path (public_stigma -> self_stigma) is statistically significant The b path (self_stigma -> help_seeking_attitudes) is statistically significant The total effect (public_stigma -> help_seeking_attitudes) is statistically significant The direct effect (public_stigma -> help_seeking_attitudes when self_stigma is in the model) is marginally significant The indirect effect (ab) is statistically significant The model accounts for 31% of the variance in help-seeking attitudes (DV) and 30% of the variance in self-stigma

Analysis 4: The moderated mediation - a combined analysis

# Specify the mediation model
Combined <- '
  # Direct effect (path C)
  help_seeking_attitudes ~ c * public_stigma
  
  # Mediation model (paths A and B)
  familism ~ a * public_stigma
  help_seeking_attitudes ~ b * self_stigma
  
  # Moderation effect on path A
  self_stigma ~ d * familism
  
  # Moderation effect on path B
  help_seeking_attitudes ~ e * familism
'

# Fit the model
fit <- sem(Combined, data = d)

# Summarize the results
summary(fit)
## lavaan 0.6.16 ended normally after 1 iteration
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                         8
## 
##   Number of observations                           257
## 
## Model Test User Model:
##                                                       
##   Test statistic                                91.302
##   Degrees of freedom                                 1
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Standard errors                             Standard
##   Information                                 Expected
##   Information saturated (h1) model          Structured
## 
## Regressions:
##                            Estimate  Std.Err  z-value  P(>|z|)
##   help_seeking_attitudes ~                                    
##     publc_stgm (c)           -0.231    0.090   -2.563    0.010
##   familism ~                                                  
##     publc_stgm (a)           -0.176    0.092   -1.908    0.056
##   help_seeking_attitudes ~                                    
##     self_stigm (b)           -0.633    0.073   -8.694    0.000
##   self_stigma ~                                               
##     familism   (d)           -0.151    0.052   -2.924    0.003
##   help_seeking_attitudes ~                                    
##     familism   (e)            0.133    0.062    2.165    0.030
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##    .hlp_skng_tttds    0.910    0.080   11.336    0.000
##    .familism          0.963    0.085   11.336    0.000
##    .self_stigma       0.668    0.059   11.336    0.000
set.seed(230925) #required for reproducible results because lavaan introduces randomness into the calculations
Combined_fit <- lavaan::sem(Combined, data = d, se = "bootstrap", missing = 'fiml', bootstrap = 1000)
cFITsum <- lavaan::summary(Combined_fit, standardized = TRUE, rsq=T, ci=TRUE)    
cParamEsts <- lavaan::parameterEstimates(Combined_fit, boot.ci.type = "bca.simple", standardized=TRUE)
cFITsum
## lavaan 0.6.16 ended normally after 1 iteration
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        11
## 
##   Number of observations                           257
##   Number of missing patterns                         1
## 
## Model Test User Model:
##                                                       
##   Test statistic                                91.302
##   Degrees of freedom                                 1
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Standard errors                            Bootstrap
##   Number of requested bootstrap draws             1000
##   Number of successful bootstrap draws            1000
## 
## Regressions:
##                            Estimate  Std.Err  z-value  P(>|z|) ci.lower
##   help_seeking_attitudes ~                                             
##     publc_stgm (c)           -0.231    0.123   -1.883    0.060   -0.479
##   familism ~                                                           
##     publc_stgm (a)           -0.176    0.100   -1.760    0.078   -0.377
##   help_seeking_attitudes ~                                             
##     self_stigm (b)           -0.633    0.101   -6.242    0.000   -0.842
##   self_stigma ~                                                        
##     familism   (d)           -0.151    0.063   -2.379    0.017   -0.287
##   help_seeking_attitudes ~                                             
##     familism   (e)            0.133    0.063    2.118    0.034    0.016
##  ci.upper   Std.lv  Std.all
##                            
##     0.004   -0.231   -0.137
##                            
##     0.010   -0.176   -0.118
##                            
##    -0.431   -0.633   -0.468
##                            
##    -0.034   -0.151   -0.179
##                            
##     0.262    0.133    0.117
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|) ci.lower ci.upper
##    .hlp_skng_tttds    7.024    0.366   19.202    0.000    6.258    7.753
##    .familism          4.065    0.226   18.022    0.000    3.629    4.506
##    .self_stigma       2.872    0.241   11.924    0.000    2.442    3.387
##    Std.lv  Std.all
##     7.024    6.256
##     4.065    4.114
##     2.872    3.456
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|) ci.lower ci.upper
##    .hlp_skng_tttds    0.910    0.125    7.265    0.000    0.665    1.147
##    .familism          0.963    0.085   11.305    0.000    0.786    1.129
##    .self_stigma       0.668    0.061   10.906    0.000    0.549    0.790
##    Std.lv  Std.all
##     0.910    0.722
##     0.963    0.986
##     0.668    0.968
## 
## R-Square:
##                    Estimate
##     hlp_skng_tttds    0.278
##     familism          0.014
##     self_stigma       0.032
cParamEsts
##                       lhs op                    rhs label    est    se      z
## 1  help_seeking_attitudes  ~          public_stigma     c -0.231 0.123 -1.883
## 2                familism  ~          public_stigma     a -0.176 0.100 -1.760
## 3  help_seeking_attitudes  ~            self_stigma     b -0.633 0.101 -6.242
## 4             self_stigma  ~               familism     d -0.151 0.063 -2.379
## 5  help_seeking_attitudes  ~               familism     e  0.133 0.063  2.118
## 6  help_seeking_attitudes ~~ help_seeking_attitudes        0.910 0.125  7.265
## 7                familism ~~               familism        0.963 0.085 11.305
## 8             self_stigma ~~            self_stigma        0.668 0.061 10.906
## 9           public_stigma ~~          public_stigma        0.443 0.000     NA
## 10 help_seeking_attitudes ~1                               7.024 0.366 19.202
## 11               familism ~1                               4.065 0.226 18.022
## 12            self_stigma ~1                               2.872 0.241 11.924
## 13          public_stigma ~1                               2.216 0.000     NA
##    pvalue ci.lower ci.upper std.lv std.all std.nox
## 1   0.060   -0.505   -0.018 -0.231  -0.137  -0.206
## 2   0.078   -0.377    0.010 -0.176  -0.118  -0.178
## 3   0.000   -0.817   -0.422 -0.633  -0.468  -0.468
## 4   0.017   -0.280   -0.024 -0.151  -0.179  -0.179
## 5   0.034    0.011    0.259  0.133   0.117   0.117
## 6   0.000    0.705    1.190  0.910   0.722   0.722
## 7   0.000    0.822    1.173  0.963   0.986   0.986
## 8   0.000    0.565    0.808  0.668   0.968   0.968
## 9      NA    0.443    0.443  0.443   1.000   0.443
## 10  0.000    6.277    7.765  7.024   6.256   6.256
## 11  0.000    3.625    4.505  4.065   4.114   4.114
## 12  0.000    2.432    3.377  2.872   3.456   3.456
## 13     NA    2.216    2.216  2.216   3.332   2.216

Visualization

# Calculate mean and standard deviation of familism
mean_familism <- mean(d$familism)
sd_familism <- sd(d$familism)

# Create a new variable indicating high, middle, and low familism
d$familism_group <- cut(
  d$familism,
  breaks = c(-Inf, mean_familism - sd_familism, mean_familism + sd_familism, Inf),
  labels = c("Low", "Middle", "High"),
  include.lowest = TRUE
)
# Load necessary libraries
library(stats)
library(ggplot2)

# Create a moderation plot using ggplot2
ggplot(d, aes(x = public_stigma, y = self_stigma, color = familism_group)) +
  geom_smooth(method = "lm", se = FALSE, size = 1) +
  labs(x = "Public Stigma", y = "Self-Stigma") +
  scale_color_manual(values = c("#e76f51", "#264653", "#2a9d8f")) +  # Adjust colors as needed
  theme_minimal() +
  ggtitle("Moderating Influence of Familism on Public Stigma and Self-Stigma")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using formula = 'y ~ x'