An organizational psychologist wants to know whether employees who perceive more social support at work go on to experience less job burnout, and, if so, whether that relationship runs through how well-balanced employees feel their work and personal life are, and through how much control employees feel they have over their own job.
You have anonymized survey data from 250 employees: perceived social
support, perceived work-life balance, perceived job control, average
weekly hours worked, and a job burnout score. The data is
workplace_burnout_lab.csv.
| Variable | Type | Description |
|---|---|---|
| employee_id | Integer | Anonymous employee identifier, 1-250 |
| social_support | Continuous | Perceived workplace social support score, 0-100 (higher = more supported) |
| work_life_balance | Continuous | Perceived work-life balance score, 0-100 (mediator) |
| job_control | Continuous | Perceived control over one’s own job score, 0-100 (mediator) |
| weekly_hours | Continuous | Average hours worked per week over the preceding month (covariate, controlled on burnout) |
| burnout | Continuous | Job burnout score, 0-100 (higher = more burnout) |
This practical builds a path model in stages – a total effect, a
single-mediator model, and finally a two-parallel-mediator model – fit
with lavaan, with bootstrapped confidence intervals for
every indirect effect.
Work through the tasks below in order. Each part builds on the model
from the part before it. Use workplace_burnout_lab.csv.
Part A – Getting to know the data
social_support,
work_life_balance, job_control,
weekly_hours, and burnout.work_life_balance against
social_support and of job_control against
social_support. Describe, in a sentence or two, what each
plot suggests.Part B – Research question 1: does perceived social support predict burnout at all?
burnout from
social_support alone. Report the coefficient, its
significance test, and state what this coefficient represents in a
mediation framework.Part C – Research question 2: is the social-support-burnout relationship carried through work-life balance?
lavaan path model with
work_life_balance as a single mediator between
social_support and burnout, entering
weekly_hours as a covariate on burnout. Label
the \(a\), \(b\), and \(c'\) paths, and define the indirect and
total effects using :=. Fit the model with
se = "bootstrap" and bootstrap = 5000.a \(\times\) b) and its percentile
confidence interval. Does the interval exclude zero?Part D – Research question 3: does adding job control as a second mediator change the picture?
job_control alongside
work_life_balance, each with its own \(a\)-path from social_support
and its own \(b\)-path to
burnout. Label every path and define both specific indirect
effects, their sum, and the total effect.work_life_balance and via job_control) with
its bootstrapped confidence interval.:=, report it with
its bootstrapped 95% confidence interval, and state which mediator, if
either, carries the larger indirect effect.Part E – Reporting
This walkthrough builds the burnout path model in stages, from a bare total effect through a single-mediator model to a two-parallel-mediator model, testing the indirect effects at every stage.
The organizational psychologist’s question has three layers, and each should be answered by a separate, explicit model rather than by fitting the most complicated model first and hoping to read everything off it at once. First, is there any relationship at all between perceived social support and burnout. Second, once work-life balance is placed between them as a hypothesized mediator, how much of that relationship runs through work-life balance, and does a direct path from social support to burnout remain once work-life balance is accounted for. Third, once job control is added as a second, parallel mediator, does the picture change – does the direct path shrink further, and how does the burden of explaining the social-support-burnout relationship divide between the two mediators.
d <- read.csv("data/workplace_burnout_lab.csv")
str(d)
## 'data.frame': 250 obs. of 6 variables:
## $ employee_id : int 1 2 3 4 5 6 7 8 9 10 ...
## $ social_support : num 70.9 47.2 48.3 52.2 58.9 40.3 54.1 35.4 52.2 54.1 ...
## $ work_life_balance: num 48.1 43.9 54.6 56.3 51.6 71.3 46.6 38.5 48.1 60.5 ...
## $ job_control : num 52.5 51.2 27.9 42.3 59.4 38.9 45.8 29.8 41.3 41.6 ...
## $ weekly_hours : num 47.2 36.4 37.8 36.5 40.1 49.1 34.4 45.6 47.9 42.3 ...
## $ burnout : num 34.6 38.6 29.8 37.3 42.7 38.7 46 44.5 55.4 18.9 ...
d %>%
summarise(n = n(),
social_support_M = mean(social_support), social_support_SD = sd(social_support),
work_life_balance_M = mean(work_life_balance), work_life_balance_SD = sd(work_life_balance),
job_control_M = mean(job_control), job_control_SD = sd(job_control),
weekly_hours_M = mean(weekly_hours), weekly_hours_SD = sd(weekly_hours),
burnout_M = mean(burnout), burnout_SD = sd(burnout)) %>%
kable(digits = 2)
| n | social_support_M | social_support_SD | work_life_balance_M | work_life_balance_SD | job_control_M | job_control_SD | weekly_hours_M | weekly_hours_SD | burnout_M | burnout_SD |
|---|---|---|---|---|---|---|---|---|---|---|
| 250 | 49.12 | 9.71 | 46.93 | 9.69 | 39.4 | 9.83 | 45 | 6.02 | 44.15 | 12.31 |
d %>%
select(social_support, work_life_balance, job_control, weekly_hours, burnout) %>%
cor() %>%
kable(digits = 3)
| social_support | work_life_balance | job_control | weekly_hours | burnout | |
|---|---|---|---|---|---|
| social_support | 1.000 | 0.382 | 0.357 | 0.077 | -0.259 |
| work_life_balance | 0.382 | 1.000 | 0.176 | -0.025 | -0.509 |
| job_control | 0.357 | 0.176 | 1.000 | -0.050 | -0.318 |
| weekly_hours | 0.077 | -0.025 | -0.050 | 1.000 | 0.411 |
| burnout | -0.259 | -0.509 | -0.318 | 0.411 | 1.000 |
Social support correlates positively with both work-life balance and job control, and both of those correlate negatively with burnout – exactly the pattern a mediation hypothesis predicts. Weekly hours correlates only weakly with social support and with the two candidate mediators, but more noticeably with burnout itself, which is why it is entered as a covariate on the outcome rather than treated as another mediator.
d %>%
select(social_support, work_life_balance, job_control) %>%
pivot_longer(cols = c(work_life_balance, job_control),
names_to = "mediator", values_to = "mediator_value") %>%
mutate(mediator = recode(mediator,
work_life_balance = "Work-life balance",
job_control = "Job control")) %>%
ggplot(aes(social_support, mediator_value)) +
geom_point(alpha = 0.6, color = ntnublue) +
geom_smooth(method = "lm", se = FALSE, color = red) +
facet_wrap(~ mediator, scales = "free_y") +
labs(x = "Perceived social support", y = "Mediator value",
title = "a-paths: social support and each candidate mediator")
Both candidate mediators rise with perceived social support, roughly linearly, which is consistent with both being viable carriers of a social-support-to-burnout effect.
Each research question above concerns a directional chain of
relationships among continuous variables, not just a single
predictor-outcome pair, which is exactly the setting for path analysis:
a system of regression equations fit simultaneously, with indirect
effects defined as products of paths. Every model below is fit with
lavaan::sem(), using se = "bootstrap" so that
every indirect effect gets a percentile bootstrap confidence interval
rather than relying on the (often poorly-behaved) normal-theory standard
error of a product of coefficients.
model3 <- '
burnout ~ b1*work_life_balance + b2*job_control + cprime*social_support + weekly_hours
work_life_balance ~ a1*social_support
job_control ~ a2*social_support
indirect_wlb := a1*b1
indirect_jc := a2*b2
total_indirect := indirect_wlb + indirect_jc
total := total_indirect + cprime
ind_diff := indirect_wlb - indirect_jc
'
fit3 <- sem(model3, data = d, se = "bootstrap", bootstrap = 5000)
summary(fit3, standardized = TRUE, fit.measures = TRUE)
## lavaan 0.6-21 ended normally after 1 iteration
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 9
##
## Number of observations 250
##
## Model Test User Model:
##
## Test statistic 3.036
## Degrees of freedom 3
## P-value (Chi-square) 0.386
##
## Model Test Baseline Model:
##
## Test statistic 233.100
## Degrees of freedom 9
## P-value 0.000
##
## User Model versus Baseline Model:
##
## Comparative Fit Index (CFI) 1.000
## Tucker-Lewis Index (TLI) 1.000
##
## Loglikelihood and Information Criteria:
##
## Loglikelihood user model (H0) -2714.316
## Loglikelihood unrestricted model (H1) -2712.798
##
## Akaike (AIC) 5446.632
## Bayesian (BIC) 5478.325
## Sample-size adjusted Bayesian (SABIC) 5449.794
##
## Root Mean Square Error of Approximation:
##
## RMSEA 0.007
## 90 Percent confidence interval - lower 0.000
## 90 Percent confidence interval - upper 0.107
## P-value H_0: RMSEA <= 0.050 0.625
## P-value H_0: RMSEA >= 0.080 0.162
##
## Standardized Root Mean Square Residual:
##
## SRMR 0.033
##
## Parameter Estimates:
##
## Standard errors Bootstrap
## Number of requested bootstrap draws 5000
## Number of successful bootstrap draws 5000
##
## Regressions:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## burnout ~
## wrk_lf_ (b1) -0.567 0.066 -8.638 0.000 -0.567 -0.455
## jb_cntr (b2) -0.254 0.069 -3.691 0.000 -0.254 -0.207
## scl_spp (cprm) -0.059 0.064 -0.923 0.356 -0.059 -0.047
## wkly_hr 0.805 0.106 7.592 0.000 0.805 0.401
## work_life_balance ~
## scl_spp (a1) 0.381 0.054 7.012 0.000 0.381 0.382
## job_control ~
## scl_spp (a2) 0.362 0.061 5.931 0.000 0.362 0.357
##
## Variances:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## .burnout 80.684 6.680 12.078 0.000 80.684 0.556
## .work_life_blnc 79.847 7.077 11.282 0.000 79.847 0.854
## .job_control 83.951 7.147 11.747 0.000 83.951 0.872
##
## Defined Parameters:
## Estimate Std.Err z-value P(>|z|) Std.lv Std.all
## indirect_wlb -0.216 0.040 -5.346 0.000 -0.216 -0.174
## indirect_jc -0.092 0.028 -3.247 0.001 -0.092 -0.074
## total_indirect -0.308 0.049 -6.225 0.000 -0.308 -0.248
## total -0.367 0.070 -5.209 0.000 -0.367 -0.295
## ind_diff -0.124 0.049 -2.518 0.012 -0.124 -0.100
pe3 <- parameterEstimates(fit3, ci = TRUE, boot.ci.type = "perc")
pe3 %>% kable(digits = 3)
| lhs | op | rhs | label | est | se | z | pvalue | ci.lower | ci.upper |
|---|---|---|---|---|---|---|---|---|---|
| burnout | ~ | work_life_balance | b1 | -0.567 | 0.066 | -8.638 | 0.000 | -0.696 | -0.437 |
| burnout | ~ | job_control | b2 | -0.254 | 0.069 | -3.691 | 0.000 | -0.388 | -0.114 |
| burnout | ~ | social_support | cprime | -0.059 | 0.064 | -0.923 | 0.356 | -0.186 | 0.063 |
| burnout | ~ | weekly_hours | 0.805 | 0.106 | 7.592 | 0.000 | 0.602 | 1.021 | |
| work_life_balance | ~ | social_support | a1 | 0.381 | 0.054 | 7.012 | 0.000 | 0.272 | 0.487 |
| job_control | ~ | social_support | a2 | 0.362 | 0.061 | 5.931 | 0.000 | 0.240 | 0.481 |
| burnout | burnout | 80.684 | 6.680 | 12.078 | 0.000 | 66.186 | 92.480 | ||
| work_life_balance | work_life_balance | 79.847 | 7.077 | 11.282 | 0.000 | 65.858 | 93.964 | ||
| job_control | job_control | 83.951 | 7.147 | 11.747 | 0.000 | 69.672 | 97.473 | ||
| social_support | social_support | 93.853 | 0.000 | NA | NA | 93.853 | 93.853 | ||
| social_support | weekly_hours | 4.496 | 0.000 | NA | NA | 4.496 | 4.496 | ||
| weekly_hours | weekly_hours | 36.043 | 0.000 | NA | NA | 36.043 | 36.043 | ||
| indirect_wlb | := | a1*b1 | indirect_wlb | -0.216 | 0.040 | -5.346 | 0.000 | -0.301 | -0.144 |
| indirect_jc | := | a2*b2 | indirect_jc | -0.092 | 0.028 | -3.247 | 0.001 | -0.151 | -0.039 |
| total_indirect | := | indirect_wlb+indirect_jc | total_indirect | -0.308 | 0.049 | -6.225 | 0.000 | -0.408 | -0.214 |
| total | := | total_indirect+cprime | total | -0.367 | 0.070 | -5.209 | 0.000 | -0.502 | -0.229 |
| ind_diff | := | indirect_wlb-indirect_jc | ind_diff | -0.124 | 0.049 | -2.518 | 0.012 | -0.225 | -0.031 |
Both specific indirect effects are in the expected direction. Via work-life balance, the indirect effect is -0.216, 95% CI [-0.301, -0.144]. Via job control, the indirect effect is -0.092, 95% CI [-0.151, -0.039]. Neither interval contains zero, so both mediators carry a statistically credible share of the total effect.
Are the two indirect effects significantly different from each other?
Their difference, ind_diff := indirect_wlb - indirect_jc,
is -0.124, 95% CI [-0.225, -0.031]. The interval does not contain zero,
so the two indirect effects are significantly different: the indirect
effect through work-life balance is significantly larger (more negative)
than the indirect effect through job control.
The direct effect \(c'\) in this model is -0.059. Compare its \(p\)-value, and the chi-square difference test below, against Stage 2’s conclusion.
model3_constrained <- '
burnout ~ b1*work_life_balance + b2*job_control + 0*social_support + weekly_hours
work_life_balance ~ a1*social_support
job_control ~ a2*social_support
indirect_wlb := a1*b1
indirect_jc := a2*b2
'
fit3_constrained <- sem(model3_constrained, data = d, se = "bootstrap", bootstrap = 5000)
lrt3 <- anova(fit3, fit3_constrained)
lrt3
##
## Chi-Squared Difference Test
##
## Df AIC BIC Chisq Chisq diff RMSEA Df diff Pr(>Chisq)
## fit3 3 5447 5478 3.04
## fit3_constrained 4 5445 5474 3.80 0.767 0 1 0.38
As in Stage 2, this table compares the fit of the full model against a model with \(c'\) fixed to zero, on one degree of freedom. Here the test is not significant (\(\Delta\chi^2(1)\) = 0.77, \(p\) = 0.38): fixing \(c'\) to zero does not worsen fit, so with both mediators in the model the mediation is full. This move from a significant test (Stage 2) to a non-significant one (here) is a substantively important finding in its own right: it means the single-mediator model in Stage 2 looked like partial mediation only because a second, genuine mediating route (through job control) had not yet been modeled and was instead leaking into the apparent direct effect. Once both mediators are in the model, social support’s relationship with burnout is explained entirely by these two routes, which is full mediation by the pair of mediators taken together, even though each one alone would tell only part of the story.
lavaanPlot(model = fit3, coefs = TRUE, stand = TRUE, stars = "regress",
node_options = list(shape = "box", fontname = "Helvetica"),
edge_options = list(color = "grey40"))
effects2 <- pe2 %>%
filter(label %in% c("cprime", "a", "b", "indirect", "total")) %>%
transmute(Model = "Stage 2: single mediator (work-life balance)",
Effect = recode(label,
a = "a-path (support -> work-life balance)",
b = "b-path (work-life balance -> burnout)",
cprime = "Direct effect (c')",
indirect = "Indirect (via work-life balance)",
total = "Total effect"),
Estimate = est, `CI lower` = ci.lower, `CI upper` = ci.upper)
effects3 <- pe3 %>%
filter(label %in% c("cprime", "a1", "a2", "b1", "b2",
"indirect_wlb", "indirect_jc", "total_indirect", "total", "ind_diff")) %>%
transmute(Model = "Stage 3: two parallel mediators",
Effect = recode(label,
a1 = "a1-path (support -> work-life balance)",
a2 = "a2-path (support -> job control)",
b1 = "b1-path (work-life balance -> burnout)",
b2 = "b2-path (job control -> burnout)",
cprime = "Direct effect (c')",
indirect_wlb = "Indirect (via work-life balance)",
indirect_jc = "Indirect (via job control)",
total_indirect = "Total indirect",
total = "Total effect",
ind_diff = "Difference between the two indirect effects (WLB - job control)"),
Estimate = est, `CI lower` = ci.lower, `CI upper` = ci.upper)
bind_rows(effects2, effects3) %>% kable(digits = 3)
| Model | Effect | Estimate | CI lower | CI upper |
|---|---|---|---|---|
| Stage 2: single mediator (work-life balance) | b-path (work-life balance -> burnout) | -0.578 | -0.709 | -0.451 |
| Stage 2: single mediator (work-life balance) | Direct effect (c’) | -0.148 | -0.275 | -0.026 |
| Stage 2: single mediator (work-life balance) | a-path (support -> work-life balance) | 0.381 | 0.271 | 0.489 |
| Stage 2: single mediator (work-life balance) | Indirect (via work-life balance) | -0.220 | -0.307 | -0.143 |
| Stage 2: single mediator (work-life balance) | Total effect | -0.368 | -0.504 | -0.227 |
| Stage 3: two parallel mediators | b1-path (work-life balance -> burnout) | -0.567 | -0.696 | -0.437 |
| Stage 3: two parallel mediators | b2-path (job control -> burnout) | -0.254 | -0.388 | -0.114 |
| Stage 3: two parallel mediators | Direct effect (c’) | -0.059 | -0.186 | 0.063 |
| Stage 3: two parallel mediators | a1-path (support -> work-life balance) | 0.381 | 0.272 | 0.487 |
| Stage 3: two parallel mediators | a2-path (support -> job control) | 0.362 | 0.240 | 0.481 |
| Stage 3: two parallel mediators | Indirect (via work-life balance) | -0.216 | -0.301 | -0.144 |
| Stage 3: two parallel mediators | Indirect (via job control) | -0.092 | -0.151 | -0.039 |
| Stage 3: two parallel mediators | Total indirect | -0.308 | -0.408 | -0.214 |
| Stage 3: two parallel mediators | Total effect | -0.367 | -0.502 | -0.229 |
| Stage 3: two parallel mediators | Difference between the two indirect effects (WLB - job control) | -0.124 | -0.225 | -0.031 |
Perceived social support relates to burnout on its own (Stage 1). Once work-life balance is entered as a single mediator (Stage 2), a substantial share of that relationship runs through work-life balance, and a formal chi-square difference test shows the remaining direct path is still needed, consistent with partial mediation. Once job control is entered as a second, parallel mediator (Stage 3), the picture becomes more complete: both mediators carry a statistically credible share of the effect, and the direct path that remained significant in Stage 2 is no longer needed once both routes are represented, consistent with full mediation once both work-life balance and job control are modeled together. A single-mediator model, however carefully estimated, could have left a genuine explanatory route folded into what looked like an unexplained direct effect.
Perceived workplace social support was associated with lower job burnout (total effect \(c\), Stage 1). This relationship was partially carried by perceived work-life balance: the bootstrapped indirect effect through work-life balance was statistically distinguishable from zero, and the remaining direct effect of social support on burnout was still required by a formal chi-square difference test (Stage 2). Extending the model to include perceived job control as a second, parallel mediator (Stage 3) showed that job control also carried a statistically credible share of the effect, and that the direct path from social support to burnout was no longer required once both mediators were represented together, consistent with full mediation once both proposed mechanisms are modeled jointly rather than one at a time. Because employees were not randomly assigned to levels of perceived social support, these results describe a statistically well-supported pattern of association and are consistent with, but do not on their own establish, a causal chain running from social support through work-life balance and job control to burnout.
Expected answers to the Questions above. The reasoning for each is in the Guided Walkthrough section; this section states the answers directly, reusing the models already fitted there.
Part A
Part B
summary(fit_total) above for \(SE\), \(t\), \(df\), and \(p\)). In a mediation framework this is the
total effect, \(c\): the overall
relationship between social support and burnout before any mediator is
introduced.Part C
model2 object and fit2 above for
the labeled lavaan syntax and the fitted model.anova(fit2, fit2_constrained) output above for both models’
chi-square and \(df\) and the
difference row). The direct path is therefore still needed, so work-life
balance alone only partially mediates the relationship between social
support and burnout.Part D
model3 object and fit3 above for
the labeled lavaan syntax and the fitted model, including
both specific indirect effects, their sum, and the total effect.anova(fit3, fit3_constrained) output above). The conclusion
therefore changes from partial mediation (Question 8) to full mediation:
work-life balance and job control together account for the relationship
between social support and burnout. It changes because job control is a
genuine second mediating route; in the single-mediator model its share
of the effect had nowhere to go but the direct path, which made \(c'\) look larger than it is.Part E
lavaanPlot diagram of fit3 above
(and the lavaanPlot diagram of fit2 for the
single-mediator model).Perceived workplace social support was associated with lower job burnout among the 250 employees in this sample. Part of that association was explained by perceived work-life balance, and, in a fuller model, part was also explained by perceived job control; together, these two factors accounted for the entire statistically detectable relationship between social support and burnout, with no reliably remaining direct path once both were modeled. This suggests that interventions aimed at improving employees’ sense of work-life balance and their sense of control over their own job are two concrete, and apparently complementary, routes through which greater workplace social support could translate into lower burnout. Because employees were not randomly assigned to levels of social support, work-life balance, or job control, these findings describe a well-supported statistical pattern rather than a demonstrated causal effect, and unmeasured factors, such as a supervisor’s general management style, could plausibly influence several of these variables at once.
Common errors and points to watch for
weekly_hours) as though it were a
third mediator, when it was never modeled as a consequence of
social_support.sessionInfo()
## R version 4.4.2 (2024-10-31)
## Platform: aarch64-apple-darwin20
## Running under: macOS 27.0.1
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## time zone: Europe/Oslo
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] kableExtra_1.4.0 knitr_1.51 lavaanPlot_0.8.1 lavaan_0.6-21 lubridate_1.9.5 forcats_1.0.1
## [7] stringr_1.6.0 dplyr_1.2.0 purrr_1.2.1 readr_2.2.0 tidyr_1.3.2 tibble_3.3.1
## [13] ggplot2_4.0.2 tidyverse_2.0.0 pacman_0.5.1
##
## loaded via a namespace (and not attached):
## [1] DiagrammeR_1.0.11 sass_0.4.10 generics_0.1.4 xml2_1.5.2 lattice_0.22-9 stringi_1.8.7
## [7] hms_1.1.4 digest_0.6.39 magrittr_2.0.4 evaluate_1.0.5 grid_4.4.2 timechange_0.4.0
## [13] RColorBrewer_1.1-3 fastmap_1.2.0 Matrix_1.7-5 jsonlite_2.0.0 mgcv_1.9-4 viridisLite_0.4.3
## [19] scales_1.4.0 pbivnorm_0.6.0 textshaping_1.0.5 jquerylib_0.1.4 mnormt_2.1.2 cli_3.6.5
## [25] rlang_1.1.7 visNetwork_2.1.4 splines_4.4.2 withr_3.0.2 cachem_1.1.0 yaml_2.3.12
## [31] otel_0.2.0 parallel_4.4.2 tools_4.4.2 tzdb_0.5.0 vctrs_0.7.2 R6_2.6.1
## [37] stats4_4.4.2 lifecycle_1.0.5 htmlwidgets_1.6.4 pkgconfig_2.0.3 pillar_1.11.1 bslib_0.10.0
## [43] gtable_0.3.6 glue_1.8.0 systemfonts_1.3.2 xfun_0.57 tidyselect_1.2.1 rstudioapi_0.18.0
## [49] farver_2.1.2 nlme_3.1-168 htmltools_0.5.9 labeling_0.4.3 svglite_2.2.2 rmarkdown_2.30
## [55] compiler_4.4.2 S7_0.2.1 quadprog_1.5-8