PyProcessMacro 1.0.14__tar.gz → 2.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/PKG-INFO +134 -6
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/PyProcessMacro.egg-info/PKG-INFO +134 -6
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/PyProcessMacro.egg-info/SOURCES.txt +5 -4
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/PyProcessMacro.egg-info/requires.txt +4 -0
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/README.md +130 -5
- pyprocessmacro-2.1.0/pyprocessmacro/__init__.py +10 -0
- pyprocessmacro-2.1.0/pyprocessmacro/bootstrap.py +242 -0
- pyprocessmacro-2.1.0/pyprocessmacro/effsize.py +77 -0
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/pyprocessmacro/models.py +165 -118
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/pyprocessmacro/process.py +202 -83
- pyprocessmacro-2.1.0/pyprocessmacro/serial.py +218 -0
- pyprocessmacro-2.1.0/pyprocessmacro/tidy.py +219 -0
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/pyprocessmacro/utils.py +32 -13
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/pyproject.toml +2 -1
- pyprocessmacro-1.0.14/pyprocessmacro/__init__.py +0 -9
- pyprocessmacro-1.0.14/pyprocessmacro/models.pyi +0 -228
- pyprocessmacro-1.0.14/pyprocessmacro/process.pyi +0 -163
- pyprocessmacro-1.0.14/pyprocessmacro/utils.pyi +0 -92
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/LICENSE.txt +0 -0
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/MANIFEST.in +0 -0
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/PyProcessMacro.egg-info/dependency_links.txt +0 -0
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/PyProcessMacro.egg-info/top_level.txt +0 -0
- {pyprocessmacro-1.0.14 → pyprocessmacro-2.1.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyProcessMacro
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: A Python library for moderation, mediation and conditional process analysis. Based on Andrew F. Hayes' Process Macro.
|
|
5
5
|
Author-email: Quentin André <quentin.andre@insead.edu>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -27,8 +27,11 @@ Requires-Dist: pandas>=2.0
|
|
|
27
27
|
Requires-Dist: scipy>=1.10
|
|
28
28
|
Requires-Dist: matplotlib>=3.7
|
|
29
29
|
Requires-Dist: seaborn>=0.13
|
|
30
|
+
Provides-Extra: statsmodels
|
|
31
|
+
Requires-Dist: statsmodels>=0.14; extra == "statsmodels"
|
|
30
32
|
Provides-Extra: test
|
|
31
33
|
Requires-Dist: pytest>=8; extra == "test"
|
|
34
|
+
Requires-Dist: statsmodels>=0.14; extra == "test"
|
|
32
35
|
Dynamic: license-file
|
|
33
36
|
|
|
34
37
|
PyProcessMacro: A Python Implementation of Andrew F. Hayes' 'Process' Macro
|
|
@@ -61,14 +64,16 @@ softwaress. PyProcessMacro is released under a MIT license.
|
|
|
61
64
|
# Features
|
|
62
65
|
|
|
63
66
|
In the current version, PyProcessMacro replicates the following features from the original Process Macro v2.16:
|
|
64
|
-
* All models (1 to 76)
|
|
65
|
-
|
|
67
|
+
* All models (1 to 76) are supported. Models 1 to 5 and 7 to 76 are tested for accuracy against the output of the
|
|
68
|
+
original Process macro (see `tests/test_models_accuracy.py`); Model 6 (serial mediation, added in 2.1) is tested
|
|
69
|
+
against statsmodels-based reference computations.
|
|
66
70
|
* Estimation of binary/continuous outcome variables. The binary outcomes are estimated in Logit using the
|
|
67
71
|
Newton-Raphson convergence algorithm, the continuous variables are estimated using OLS.
|
|
68
72
|
* All statistics reported by Process:
|
|
69
73
|
* Variable parameters for outcome models
|
|
70
74
|
* (Conditional) direct and indirect effects
|
|
71
|
-
*
|
|
75
|
+
* The index of moderated mediation and, following PROCESS 3, the indices of partial, conditional and
|
|
76
|
+
moderated moderated mediation, whenever the indirect effect is linear in the moderator(s).
|
|
72
77
|
* Automatic generation of spotlight values for continuous/discrete moderators.
|
|
73
78
|
* Rich set of options to tweak the estimation and display of the different models: (almost) all the options from
|
|
74
79
|
Process exist in PyProcessMacro. Check the doc for more details.
|
|
@@ -90,10 +95,41 @@ In the current version, the following features have not yet been ported to PyPro
|
|
|
90
95
|
* Support for categorical independent variables.
|
|
91
96
|
* Generation of individual fixed effects for repeated measures.
|
|
92
97
|
* R² improvement from moderators in moderation models (1, 2, 3).
|
|
93
|
-
* Estimation of serial mediation (Model 6)
|
|
94
98
|
* Some options (`normal`, `varorder`, ...). PyProcessMacro will issue a warning to tell you if an option you are
|
|
95
99
|
trying to use is not implemented.
|
|
96
100
|
|
|
101
|
+
# Upgrading to 2.0
|
|
102
|
+
|
|
103
|
+
Version 2.0 corrects several statistics and tightens input handling. Reported numbers change in these ways:
|
|
104
|
+
|
|
105
|
+
* Confidence intervals of OLS coefficients and of (conditional) direct effects use t critical values with the
|
|
106
|
+
residual degrees of freedom, as PROCESS does. They were based on z, so they widen slightly; the difference is
|
|
107
|
+
visible in small samples.
|
|
108
|
+
* Adjusted R² of OLS outcome models is slightly higher: the previous value used one degree of freedom too many.
|
|
109
|
+
* Cox-Snell and Nagelkerke pseudo R² of logistic outcome models are finite for large samples instead of NaN.
|
|
110
|
+
* No index of moderated mediation is reported when a moderator sits on both the X-to-M and the M-to-Y paths
|
|
111
|
+
(models 58 to 73, 75 and 76), matching PROCESS: the indirect effect is not linear in such a moderator. The
|
|
112
|
+
`*_index_summary()` methods raise `NotImplementedError` for those models.
|
|
113
|
+
* The sample size reported after listwise deletion is the number of rows kept.
|
|
114
|
+
|
|
115
|
+
Behaviour that used to be silent now speaks up:
|
|
116
|
+
|
|
117
|
+
* A misspelled key in `modval`, or a keyword argument that is neither a variable nor an option, raises an error
|
|
118
|
+
instead of being ignored.
|
|
119
|
+
* Unsupported PROCESS options (`jn`, `effsize`, `mc`, `normal`, ...) raise a visible `UserWarning`.
|
|
120
|
+
* A logistic regression that does not converge raises `pyprocessmacro.ConvergenceError`. Bootstrap resamples
|
|
121
|
+
that fail are counted, and the bootstrap stops with an error if more resamples fail than were requested.
|
|
122
|
+
|
|
123
|
+
Removed and added:
|
|
124
|
+
|
|
125
|
+
* `plot_direct_effects()` and `plot_indirect_effects()` are removed; use `plot_conditional_direct_effects()`
|
|
126
|
+
and `plot_conditional_indirect_effects()`.
|
|
127
|
+
* `cov_type` selects the OLS covariance estimator (`"standard"`, `"HC0"`, `"HC1"`, `"HC2"` or `"HC3"`);
|
|
128
|
+
`hc3=True` remains as shorthand for `"HC3"`.
|
|
129
|
+
* `seed=None` draws a different bootstrap sample on every run, and `seed=0` is accepted.
|
|
130
|
+
* `Process.dv` names the outcome variable (`iv` is kept for compatibility).
|
|
131
|
+
* Python 3.11 or newer is required (since 1.0.14).
|
|
132
|
+
|
|
97
133
|
# Version History
|
|
98
134
|
|
|
99
135
|
## Master Versions
|
|
@@ -117,7 +153,7 @@ report and for the fix.
|
|
|
117
153
|
|
|
118
154
|
### 1.0.4
|
|
119
155
|
**Bug fix for standard error estimate in all models**
|
|
120
|
-
PyProcessMacro was, by default, using the HC3 estimator for the variance-covariance matrix instead of the
|
|
156
|
+
PyProcessMacro was, by default, using the HC3 estimator for the variance-covariance matrix instead of the standard (non-robust) estimator.
|
|
121
157
|
This has now been changed. To continue using the HC3 estimator, specify `hc3=True` when initializing the Process instance.
|
|
122
158
|
Thanks to Zoé Ziani for the bug report.
|
|
123
159
|
|
|
@@ -199,6 +235,8 @@ As you can see, the syntax for PyProcessMacro is (almost) identical to that of P
|
|
|
199
235
|
|
|
200
236
|
Once the object is initialized, you can call its `summary()` method to display the estimation results
|
|
201
237
|
|
|
238
|
+
The standardized result tables (`tidy()`, `glance()`, `augment()`) are described in section 6.
|
|
239
|
+
|
|
202
240
|
You might have noticed that there is no argument `varlist` in PyProcessMacro. This is because the list of variables
|
|
203
241
|
is automatically inferred from the variable names given to x, y, m.
|
|
204
242
|
|
|
@@ -274,6 +312,48 @@ p = Process(data=df, model=13, x="Effort", y="Success", w="Motivation", z="Skill
|
|
|
274
312
|
p.summary()
|
|
275
313
|
````
|
|
276
314
|
|
|
315
|
+
### F. Choosing the covariance estimator
|
|
316
|
+
|
|
317
|
+
By default, the standard errors of the OLS outcome models use the standard (homoskedastic) estimator. The
|
|
318
|
+
`cov_type` argument selects a heteroskedasticity-consistent estimator instead: `"HC0"`, `"HC1"`, `"HC2"` or
|
|
319
|
+
`"HC3"`. `hc3=True` is shorthand for `cov_type="HC3"`, which is what the original Process macro uses when
|
|
320
|
+
`hc3=1` is specified. Logistic outcome models always use the inverse of the Hessian.
|
|
321
|
+
|
|
322
|
+
````python
|
|
323
|
+
p = Process(data=df, model=4, x="Effort", y="Success", m=["MediationSkills"], cov_type="HC3")
|
|
324
|
+
````
|
|
325
|
+
|
|
326
|
+
### G. Serial mediation (Model 6)
|
|
327
|
+
|
|
328
|
+
In Model 6 the mediators form a chain: each mediator depends on X and on the mediators before it, and Y depends
|
|
329
|
+
on X and on every mediator. Pass two to four mediators in causal order. PyProcessMacro reports the specific
|
|
330
|
+
indirect effect through every ordered subset of mediators (three paths for two mediators, seven for three,
|
|
331
|
+
fifteen for four), labelled by the path, plus the total and the pairwise contrasts when `total=True` and
|
|
332
|
+
`contrast=True`.
|
|
333
|
+
|
|
334
|
+
````python
|
|
335
|
+
p = Process(data=df, model=6, x="Effort", y="Success", m=["Attention", "MediationSkills"], total=True)
|
|
336
|
+
p.summary()
|
|
337
|
+
````
|
|
338
|
+
|
|
339
|
+
Model 6 has no moderators, so the spotlight, floodlight and plotting methods do not apply to it. Its estimates are
|
|
340
|
+
checked against products of statsmodels coefficients and against an independent resampler; no PROCESS output for
|
|
341
|
+
Model 6 is part of the test fixtures yet, so a comparison file generated with PROCESS 2.16 would be a welcome
|
|
342
|
+
contribution.
|
|
343
|
+
|
|
344
|
+
### H. Effect sizes for the indirect effect
|
|
345
|
+
|
|
346
|
+
With `effsize=True`, PyProcessMacro also reports the partially standardized indirect effect (the indirect effect
|
|
347
|
+
divided by the standard deviation of Y) and the completely standardized indirect effect (further multiplied by the
|
|
348
|
+
standard deviation of X), each with a bootstrap confidence interval computed by standardizing within every resample,
|
|
349
|
+
as PROCESS does. The option applies to unmoderated indirect paths with a continuous outcome, that is Models 4 and 6
|
|
350
|
+
with `logit=False`.
|
|
351
|
+
|
|
352
|
+
````python
|
|
353
|
+
p = Process(data=df, model=4, x="Effort", y="Success", m=["MediationSkills"], effsize=True)
|
|
354
|
+
p.indirect_model.effect_size_summary()
|
|
355
|
+
````
|
|
356
|
+
|
|
277
357
|
## 2. Accessing the estimation results
|
|
278
358
|
|
|
279
359
|
After the `Process` object is initialized, you are not limited to printing the summary. PyProcessMacro implements the
|
|
@@ -371,6 +451,28 @@ Note that the methods are called from the `indirect_model` object! If you call `
|
|
|
371
451
|
error.
|
|
372
452
|
|
|
373
453
|
|
|
454
|
+
### E. Diagnostics and custom tests with statsmodels
|
|
455
|
+
|
|
456
|
+
Each outcome model can be handed to [statsmodels](https://www.statsmodels.org), which refits the same design
|
|
457
|
+
matrix with the same covariance estimator and returns the statsmodels results object. From there you get
|
|
458
|
+
`summary()`, custom contrasts with `t_test()` and `wald_test()`, heteroskedasticity and influence diagnostics,
|
|
459
|
+
variance inflation factors, prediction intervals, and the table formatters that accept statsmodels results.
|
|
460
|
+
statsmodels is optional: install it with `pip install pyprocessmacro[statsmodels]`.
|
|
461
|
+
|
|
462
|
+
````python
|
|
463
|
+
p = Process(data=df, model=7, x="Effort", y="Success", w="Motivation", m=["MediationSkills"], suppr_init=True)
|
|
464
|
+
|
|
465
|
+
fit = p.outcome_models["Success"].to_statsmodels() # a statsmodels RegressionResults
|
|
466
|
+
print(fit.summary())
|
|
467
|
+
fit.t_test("Effort + MediationSkills = 0")
|
|
468
|
+
|
|
469
|
+
fits = p.to_statsmodels() # every outcome model, keyed by outcome name
|
|
470
|
+
````
|
|
471
|
+
|
|
472
|
+
For a different question, statsmodels also ships `statsmodels.stats.mediation.Mediation`, Imai-style causal
|
|
473
|
+
mediation with a sensitivity analysis; it estimates a different quantity and is a useful cross-check rather than
|
|
474
|
+
a replacement for the PROCESS approach.
|
|
475
|
+
|
|
374
476
|
## 3. Spotlight and Floodlight Analysis
|
|
375
477
|
|
|
376
478
|
### A. Compute direct/indirect effects for specific values (spotlight analysis)
|
|
@@ -601,6 +703,32 @@ g = p.plot_conditional_indirect_effects(med_name="MediationSkills", x="Motivatio
|
|
|
601
703
|
````
|
|
602
704
|

|
|
603
705
|
|
|
706
|
+
## 6. Standardized results: tidy(), glance() and augment()
|
|
707
|
+
|
|
708
|
+
Every table PyProcessMacro prints is also available in a standardized form, modelled on R's broom package:
|
|
709
|
+
|
|
710
|
+
* `tidy()` returns one long DataFrame with one row per estimate and fixed column names: `component`
|
|
711
|
+
(`outcome`, `direct`, `indirect`, `total`, `contrast`, or `index_mm`, `index_pmm`, `index_mmm`, `index_cmm`),
|
|
712
|
+
`outcome`, `term`, `moderator`, one column per moderator of the model holding the spotlight value the row is
|
|
713
|
+
evaluated at, then `estimate`, `std_error`, `statistic`, `p_value`, `conf_low`, `conf_high`, `method`,
|
|
714
|
+
`conf_level` and `n_boot`. Pass `component=` to keep one kind of row.
|
|
715
|
+
* `glance()` returns one row of fit statistics per outcome model, including the log-likelihood, AIC and BIC.
|
|
716
|
+
* `augment()` returns the analysis data with `.fitted_<outcome>` and `.resid_<outcome>` columns per outcome model.
|
|
717
|
+
|
|
718
|
+
````python
|
|
719
|
+
p = Process(data=df, model=7, x="Effort", y="Success", w="Motivation", m=["MediationSkills"], suppr_init=True)
|
|
720
|
+
|
|
721
|
+
estimates = p.tidy() # every estimate
|
|
722
|
+
indirect = p.tidy("indirect") # only the conditional indirect effects
|
|
723
|
+
fit = p.glance() # R², AIC, BIC, ... per outcome model
|
|
724
|
+
residuals = p.augment(outcome="Success") # fitted values and residuals of the outcome model
|
|
725
|
+
|
|
726
|
+
estimates.to_csv("process_model7.csv", index=False)
|
|
727
|
+
````
|
|
728
|
+
|
|
729
|
+
`summary()` returns the text it prints, so `report = p.summary()` keeps a copy, and a `Process` object displayed at
|
|
730
|
+
the end of a notebook cell shows its tables as HTML.
|
|
731
|
+
|
|
604
732
|
# 7. About
|
|
605
733
|
PyProcessMacro was developed by Quentin André during his PhD in Marketing at INSEAD Business School, France.
|
|
606
734
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyProcessMacro
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: A Python library for moderation, mediation and conditional process analysis. Based on Andrew F. Hayes' Process Macro.
|
|
5
5
|
Author-email: Quentin André <quentin.andre@insead.edu>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -27,8 +27,11 @@ Requires-Dist: pandas>=2.0
|
|
|
27
27
|
Requires-Dist: scipy>=1.10
|
|
28
28
|
Requires-Dist: matplotlib>=3.7
|
|
29
29
|
Requires-Dist: seaborn>=0.13
|
|
30
|
+
Provides-Extra: statsmodels
|
|
31
|
+
Requires-Dist: statsmodels>=0.14; extra == "statsmodels"
|
|
30
32
|
Provides-Extra: test
|
|
31
33
|
Requires-Dist: pytest>=8; extra == "test"
|
|
34
|
+
Requires-Dist: statsmodels>=0.14; extra == "test"
|
|
32
35
|
Dynamic: license-file
|
|
33
36
|
|
|
34
37
|
PyProcessMacro: A Python Implementation of Andrew F. Hayes' 'Process' Macro
|
|
@@ -61,14 +64,16 @@ softwaress. PyProcessMacro is released under a MIT license.
|
|
|
61
64
|
# Features
|
|
62
65
|
|
|
63
66
|
In the current version, PyProcessMacro replicates the following features from the original Process Macro v2.16:
|
|
64
|
-
* All models (1 to 76)
|
|
65
|
-
|
|
67
|
+
* All models (1 to 76) are supported. Models 1 to 5 and 7 to 76 are tested for accuracy against the output of the
|
|
68
|
+
original Process macro (see `tests/test_models_accuracy.py`); Model 6 (serial mediation, added in 2.1) is tested
|
|
69
|
+
against statsmodels-based reference computations.
|
|
66
70
|
* Estimation of binary/continuous outcome variables. The binary outcomes are estimated in Logit using the
|
|
67
71
|
Newton-Raphson convergence algorithm, the continuous variables are estimated using OLS.
|
|
68
72
|
* All statistics reported by Process:
|
|
69
73
|
* Variable parameters for outcome models
|
|
70
74
|
* (Conditional) direct and indirect effects
|
|
71
|
-
*
|
|
75
|
+
* The index of moderated mediation and, following PROCESS 3, the indices of partial, conditional and
|
|
76
|
+
moderated moderated mediation, whenever the indirect effect is linear in the moderator(s).
|
|
72
77
|
* Automatic generation of spotlight values for continuous/discrete moderators.
|
|
73
78
|
* Rich set of options to tweak the estimation and display of the different models: (almost) all the options from
|
|
74
79
|
Process exist in PyProcessMacro. Check the doc for more details.
|
|
@@ -90,10 +95,41 @@ In the current version, the following features have not yet been ported to PyPro
|
|
|
90
95
|
* Support for categorical independent variables.
|
|
91
96
|
* Generation of individual fixed effects for repeated measures.
|
|
92
97
|
* R² improvement from moderators in moderation models (1, 2, 3).
|
|
93
|
-
* Estimation of serial mediation (Model 6)
|
|
94
98
|
* Some options (`normal`, `varorder`, ...). PyProcessMacro will issue a warning to tell you if an option you are
|
|
95
99
|
trying to use is not implemented.
|
|
96
100
|
|
|
101
|
+
# Upgrading to 2.0
|
|
102
|
+
|
|
103
|
+
Version 2.0 corrects several statistics and tightens input handling. Reported numbers change in these ways:
|
|
104
|
+
|
|
105
|
+
* Confidence intervals of OLS coefficients and of (conditional) direct effects use t critical values with the
|
|
106
|
+
residual degrees of freedom, as PROCESS does. They were based on z, so they widen slightly; the difference is
|
|
107
|
+
visible in small samples.
|
|
108
|
+
* Adjusted R² of OLS outcome models is slightly higher: the previous value used one degree of freedom too many.
|
|
109
|
+
* Cox-Snell and Nagelkerke pseudo R² of logistic outcome models are finite for large samples instead of NaN.
|
|
110
|
+
* No index of moderated mediation is reported when a moderator sits on both the X-to-M and the M-to-Y paths
|
|
111
|
+
(models 58 to 73, 75 and 76), matching PROCESS: the indirect effect is not linear in such a moderator. The
|
|
112
|
+
`*_index_summary()` methods raise `NotImplementedError` for those models.
|
|
113
|
+
* The sample size reported after listwise deletion is the number of rows kept.
|
|
114
|
+
|
|
115
|
+
Behaviour that used to be silent now speaks up:
|
|
116
|
+
|
|
117
|
+
* A misspelled key in `modval`, or a keyword argument that is neither a variable nor an option, raises an error
|
|
118
|
+
instead of being ignored.
|
|
119
|
+
* Unsupported PROCESS options (`jn`, `effsize`, `mc`, `normal`, ...) raise a visible `UserWarning`.
|
|
120
|
+
* A logistic regression that does not converge raises `pyprocessmacro.ConvergenceError`. Bootstrap resamples
|
|
121
|
+
that fail are counted, and the bootstrap stops with an error if more resamples fail than were requested.
|
|
122
|
+
|
|
123
|
+
Removed and added:
|
|
124
|
+
|
|
125
|
+
* `plot_direct_effects()` and `plot_indirect_effects()` are removed; use `plot_conditional_direct_effects()`
|
|
126
|
+
and `plot_conditional_indirect_effects()`.
|
|
127
|
+
* `cov_type` selects the OLS covariance estimator (`"standard"`, `"HC0"`, `"HC1"`, `"HC2"` or `"HC3"`);
|
|
128
|
+
`hc3=True` remains as shorthand for `"HC3"`.
|
|
129
|
+
* `seed=None` draws a different bootstrap sample on every run, and `seed=0` is accepted.
|
|
130
|
+
* `Process.dv` names the outcome variable (`iv` is kept for compatibility).
|
|
131
|
+
* Python 3.11 or newer is required (since 1.0.14).
|
|
132
|
+
|
|
97
133
|
# Version History
|
|
98
134
|
|
|
99
135
|
## Master Versions
|
|
@@ -117,7 +153,7 @@ report and for the fix.
|
|
|
117
153
|
|
|
118
154
|
### 1.0.4
|
|
119
155
|
**Bug fix for standard error estimate in all models**
|
|
120
|
-
PyProcessMacro was, by default, using the HC3 estimator for the variance-covariance matrix instead of the
|
|
156
|
+
PyProcessMacro was, by default, using the HC3 estimator for the variance-covariance matrix instead of the standard (non-robust) estimator.
|
|
121
157
|
This has now been changed. To continue using the HC3 estimator, specify `hc3=True` when initializing the Process instance.
|
|
122
158
|
Thanks to Zoé Ziani for the bug report.
|
|
123
159
|
|
|
@@ -199,6 +235,8 @@ As you can see, the syntax for PyProcessMacro is (almost) identical to that of P
|
|
|
199
235
|
|
|
200
236
|
Once the object is initialized, you can call its `summary()` method to display the estimation results
|
|
201
237
|
|
|
238
|
+
The standardized result tables (`tidy()`, `glance()`, `augment()`) are described in section 6.
|
|
239
|
+
|
|
202
240
|
You might have noticed that there is no argument `varlist` in PyProcessMacro. This is because the list of variables
|
|
203
241
|
is automatically inferred from the variable names given to x, y, m.
|
|
204
242
|
|
|
@@ -274,6 +312,48 @@ p = Process(data=df, model=13, x="Effort", y="Success", w="Motivation", z="Skill
|
|
|
274
312
|
p.summary()
|
|
275
313
|
````
|
|
276
314
|
|
|
315
|
+
### F. Choosing the covariance estimator
|
|
316
|
+
|
|
317
|
+
By default, the standard errors of the OLS outcome models use the standard (homoskedastic) estimator. The
|
|
318
|
+
`cov_type` argument selects a heteroskedasticity-consistent estimator instead: `"HC0"`, `"HC1"`, `"HC2"` or
|
|
319
|
+
`"HC3"`. `hc3=True` is shorthand for `cov_type="HC3"`, which is what the original Process macro uses when
|
|
320
|
+
`hc3=1` is specified. Logistic outcome models always use the inverse of the Hessian.
|
|
321
|
+
|
|
322
|
+
````python
|
|
323
|
+
p = Process(data=df, model=4, x="Effort", y="Success", m=["MediationSkills"], cov_type="HC3")
|
|
324
|
+
````
|
|
325
|
+
|
|
326
|
+
### G. Serial mediation (Model 6)
|
|
327
|
+
|
|
328
|
+
In Model 6 the mediators form a chain: each mediator depends on X and on the mediators before it, and Y depends
|
|
329
|
+
on X and on every mediator. Pass two to four mediators in causal order. PyProcessMacro reports the specific
|
|
330
|
+
indirect effect through every ordered subset of mediators (three paths for two mediators, seven for three,
|
|
331
|
+
fifteen for four), labelled by the path, plus the total and the pairwise contrasts when `total=True` and
|
|
332
|
+
`contrast=True`.
|
|
333
|
+
|
|
334
|
+
````python
|
|
335
|
+
p = Process(data=df, model=6, x="Effort", y="Success", m=["Attention", "MediationSkills"], total=True)
|
|
336
|
+
p.summary()
|
|
337
|
+
````
|
|
338
|
+
|
|
339
|
+
Model 6 has no moderators, so the spotlight, floodlight and plotting methods do not apply to it. Its estimates are
|
|
340
|
+
checked against products of statsmodels coefficients and against an independent resampler; no PROCESS output for
|
|
341
|
+
Model 6 is part of the test fixtures yet, so a comparison file generated with PROCESS 2.16 would be a welcome
|
|
342
|
+
contribution.
|
|
343
|
+
|
|
344
|
+
### H. Effect sizes for the indirect effect
|
|
345
|
+
|
|
346
|
+
With `effsize=True`, PyProcessMacro also reports the partially standardized indirect effect (the indirect effect
|
|
347
|
+
divided by the standard deviation of Y) and the completely standardized indirect effect (further multiplied by the
|
|
348
|
+
standard deviation of X), each with a bootstrap confidence interval computed by standardizing within every resample,
|
|
349
|
+
as PROCESS does. The option applies to unmoderated indirect paths with a continuous outcome, that is Models 4 and 6
|
|
350
|
+
with `logit=False`.
|
|
351
|
+
|
|
352
|
+
````python
|
|
353
|
+
p = Process(data=df, model=4, x="Effort", y="Success", m=["MediationSkills"], effsize=True)
|
|
354
|
+
p.indirect_model.effect_size_summary()
|
|
355
|
+
````
|
|
356
|
+
|
|
277
357
|
## 2. Accessing the estimation results
|
|
278
358
|
|
|
279
359
|
After the `Process` object is initialized, you are not limited to printing the summary. PyProcessMacro implements the
|
|
@@ -371,6 +451,28 @@ Note that the methods are called from the `indirect_model` object! If you call `
|
|
|
371
451
|
error.
|
|
372
452
|
|
|
373
453
|
|
|
454
|
+
### E. Diagnostics and custom tests with statsmodels
|
|
455
|
+
|
|
456
|
+
Each outcome model can be handed to [statsmodels](https://www.statsmodels.org), which refits the same design
|
|
457
|
+
matrix with the same covariance estimator and returns the statsmodels results object. From there you get
|
|
458
|
+
`summary()`, custom contrasts with `t_test()` and `wald_test()`, heteroskedasticity and influence diagnostics,
|
|
459
|
+
variance inflation factors, prediction intervals, and the table formatters that accept statsmodels results.
|
|
460
|
+
statsmodels is optional: install it with `pip install pyprocessmacro[statsmodels]`.
|
|
461
|
+
|
|
462
|
+
````python
|
|
463
|
+
p = Process(data=df, model=7, x="Effort", y="Success", w="Motivation", m=["MediationSkills"], suppr_init=True)
|
|
464
|
+
|
|
465
|
+
fit = p.outcome_models["Success"].to_statsmodels() # a statsmodels RegressionResults
|
|
466
|
+
print(fit.summary())
|
|
467
|
+
fit.t_test("Effort + MediationSkills = 0")
|
|
468
|
+
|
|
469
|
+
fits = p.to_statsmodels() # every outcome model, keyed by outcome name
|
|
470
|
+
````
|
|
471
|
+
|
|
472
|
+
For a different question, statsmodels also ships `statsmodels.stats.mediation.Mediation`, Imai-style causal
|
|
473
|
+
mediation with a sensitivity analysis; it estimates a different quantity and is a useful cross-check rather than
|
|
474
|
+
a replacement for the PROCESS approach.
|
|
475
|
+
|
|
374
476
|
## 3. Spotlight and Floodlight Analysis
|
|
375
477
|
|
|
376
478
|
### A. Compute direct/indirect effects for specific values (spotlight analysis)
|
|
@@ -601,6 +703,32 @@ g = p.plot_conditional_indirect_effects(med_name="MediationSkills", x="Motivatio
|
|
|
601
703
|
````
|
|
602
704
|

|
|
603
705
|
|
|
706
|
+
## 6. Standardized results: tidy(), glance() and augment()
|
|
707
|
+
|
|
708
|
+
Every table PyProcessMacro prints is also available in a standardized form, modelled on R's broom package:
|
|
709
|
+
|
|
710
|
+
* `tidy()` returns one long DataFrame with one row per estimate and fixed column names: `component`
|
|
711
|
+
(`outcome`, `direct`, `indirect`, `total`, `contrast`, or `index_mm`, `index_pmm`, `index_mmm`, `index_cmm`),
|
|
712
|
+
`outcome`, `term`, `moderator`, one column per moderator of the model holding the spotlight value the row is
|
|
713
|
+
evaluated at, then `estimate`, `std_error`, `statistic`, `p_value`, `conf_low`, `conf_high`, `method`,
|
|
714
|
+
`conf_level` and `n_boot`. Pass `component=` to keep one kind of row.
|
|
715
|
+
* `glance()` returns one row of fit statistics per outcome model, including the log-likelihood, AIC and BIC.
|
|
716
|
+
* `augment()` returns the analysis data with `.fitted_<outcome>` and `.resid_<outcome>` columns per outcome model.
|
|
717
|
+
|
|
718
|
+
````python
|
|
719
|
+
p = Process(data=df, model=7, x="Effort", y="Success", w="Motivation", m=["MediationSkills"], suppr_init=True)
|
|
720
|
+
|
|
721
|
+
estimates = p.tidy() # every estimate
|
|
722
|
+
indirect = p.tidy("indirect") # only the conditional indirect effects
|
|
723
|
+
fit = p.glance() # R², AIC, BIC, ... per outcome model
|
|
724
|
+
residuals = p.augment(outcome="Success") # fitted values and residuals of the outcome model
|
|
725
|
+
|
|
726
|
+
estimates.to_csv("process_model7.csv", index=False)
|
|
727
|
+
````
|
|
728
|
+
|
|
729
|
+
`summary()` returns the text it prints, so `report = p.summary()` keeps a copy, and a `Process` object displayed at
|
|
730
|
+
the end of a notebook cell shows its tables as HTML.
|
|
731
|
+
|
|
604
732
|
# 7. About
|
|
605
733
|
PyProcessMacro was developed by Quentin André during his PhD in Marketing at INSEAD Business School, France.
|
|
606
734
|
|
|
@@ -8,9 +8,10 @@ PyProcessMacro.egg-info/dependency_links.txt
|
|
|
8
8
|
PyProcessMacro.egg-info/requires.txt
|
|
9
9
|
PyProcessMacro.egg-info/top_level.txt
|
|
10
10
|
pyprocessmacro/__init__.py
|
|
11
|
+
pyprocessmacro/bootstrap.py
|
|
12
|
+
pyprocessmacro/effsize.py
|
|
11
13
|
pyprocessmacro/models.py
|
|
12
|
-
pyprocessmacro/models.pyi
|
|
13
14
|
pyprocessmacro/process.py
|
|
14
|
-
pyprocessmacro/
|
|
15
|
-
pyprocessmacro/
|
|
16
|
-
pyprocessmacro/utils.
|
|
15
|
+
pyprocessmacro/serial.py
|
|
16
|
+
pyprocessmacro/tidy.py
|
|
17
|
+
pyprocessmacro/utils.py
|
|
@@ -28,14 +28,16 @@ softwaress. PyProcessMacro is released under a MIT license.
|
|
|
28
28
|
# Features
|
|
29
29
|
|
|
30
30
|
In the current version, PyProcessMacro replicates the following features from the original Process Macro v2.16:
|
|
31
|
-
* All models (1 to 76)
|
|
32
|
-
|
|
31
|
+
* All models (1 to 76) are supported. Models 1 to 5 and 7 to 76 are tested for accuracy against the output of the
|
|
32
|
+
original Process macro (see `tests/test_models_accuracy.py`); Model 6 (serial mediation, added in 2.1) is tested
|
|
33
|
+
against statsmodels-based reference computations.
|
|
33
34
|
* Estimation of binary/continuous outcome variables. The binary outcomes are estimated in Logit using the
|
|
34
35
|
Newton-Raphson convergence algorithm, the continuous variables are estimated using OLS.
|
|
35
36
|
* All statistics reported by Process:
|
|
36
37
|
* Variable parameters for outcome models
|
|
37
38
|
* (Conditional) direct and indirect effects
|
|
38
|
-
*
|
|
39
|
+
* The index of moderated mediation and, following PROCESS 3, the indices of partial, conditional and
|
|
40
|
+
moderated moderated mediation, whenever the indirect effect is linear in the moderator(s).
|
|
39
41
|
* Automatic generation of spotlight values for continuous/discrete moderators.
|
|
40
42
|
* Rich set of options to tweak the estimation and display of the different models: (almost) all the options from
|
|
41
43
|
Process exist in PyProcessMacro. Check the doc for more details.
|
|
@@ -57,10 +59,41 @@ In the current version, the following features have not yet been ported to PyPro
|
|
|
57
59
|
* Support for categorical independent variables.
|
|
58
60
|
* Generation of individual fixed effects for repeated measures.
|
|
59
61
|
* R² improvement from moderators in moderation models (1, 2, 3).
|
|
60
|
-
* Estimation of serial mediation (Model 6)
|
|
61
62
|
* Some options (`normal`, `varorder`, ...). PyProcessMacro will issue a warning to tell you if an option you are
|
|
62
63
|
trying to use is not implemented.
|
|
63
64
|
|
|
65
|
+
# Upgrading to 2.0
|
|
66
|
+
|
|
67
|
+
Version 2.0 corrects several statistics and tightens input handling. Reported numbers change in these ways:
|
|
68
|
+
|
|
69
|
+
* Confidence intervals of OLS coefficients and of (conditional) direct effects use t critical values with the
|
|
70
|
+
residual degrees of freedom, as PROCESS does. They were based on z, so they widen slightly; the difference is
|
|
71
|
+
visible in small samples.
|
|
72
|
+
* Adjusted R² of OLS outcome models is slightly higher: the previous value used one degree of freedom too many.
|
|
73
|
+
* Cox-Snell and Nagelkerke pseudo R² of logistic outcome models are finite for large samples instead of NaN.
|
|
74
|
+
* No index of moderated mediation is reported when a moderator sits on both the X-to-M and the M-to-Y paths
|
|
75
|
+
(models 58 to 73, 75 and 76), matching PROCESS: the indirect effect is not linear in such a moderator. The
|
|
76
|
+
`*_index_summary()` methods raise `NotImplementedError` for those models.
|
|
77
|
+
* The sample size reported after listwise deletion is the number of rows kept.
|
|
78
|
+
|
|
79
|
+
Behaviour that used to be silent now speaks up:
|
|
80
|
+
|
|
81
|
+
* A misspelled key in `modval`, or a keyword argument that is neither a variable nor an option, raises an error
|
|
82
|
+
instead of being ignored.
|
|
83
|
+
* Unsupported PROCESS options (`jn`, `effsize`, `mc`, `normal`, ...) raise a visible `UserWarning`.
|
|
84
|
+
* A logistic regression that does not converge raises `pyprocessmacro.ConvergenceError`. Bootstrap resamples
|
|
85
|
+
that fail are counted, and the bootstrap stops with an error if more resamples fail than were requested.
|
|
86
|
+
|
|
87
|
+
Removed and added:
|
|
88
|
+
|
|
89
|
+
* `plot_direct_effects()` and `plot_indirect_effects()` are removed; use `plot_conditional_direct_effects()`
|
|
90
|
+
and `plot_conditional_indirect_effects()`.
|
|
91
|
+
* `cov_type` selects the OLS covariance estimator (`"standard"`, `"HC0"`, `"HC1"`, `"HC2"` or `"HC3"`);
|
|
92
|
+
`hc3=True` remains as shorthand for `"HC3"`.
|
|
93
|
+
* `seed=None` draws a different bootstrap sample on every run, and `seed=0` is accepted.
|
|
94
|
+
* `Process.dv` names the outcome variable (`iv` is kept for compatibility).
|
|
95
|
+
* Python 3.11 or newer is required (since 1.0.14).
|
|
96
|
+
|
|
64
97
|
# Version History
|
|
65
98
|
|
|
66
99
|
## Master Versions
|
|
@@ -84,7 +117,7 @@ report and for the fix.
|
|
|
84
117
|
|
|
85
118
|
### 1.0.4
|
|
86
119
|
**Bug fix for standard error estimate in all models**
|
|
87
|
-
PyProcessMacro was, by default, using the HC3 estimator for the variance-covariance matrix instead of the
|
|
120
|
+
PyProcessMacro was, by default, using the HC3 estimator for the variance-covariance matrix instead of the standard (non-robust) estimator.
|
|
88
121
|
This has now been changed. To continue using the HC3 estimator, specify `hc3=True` when initializing the Process instance.
|
|
89
122
|
Thanks to Zoé Ziani for the bug report.
|
|
90
123
|
|
|
@@ -166,6 +199,8 @@ As you can see, the syntax for PyProcessMacro is (almost) identical to that of P
|
|
|
166
199
|
|
|
167
200
|
Once the object is initialized, you can call its `summary()` method to display the estimation results
|
|
168
201
|
|
|
202
|
+
The standardized result tables (`tidy()`, `glance()`, `augment()`) are described in section 6.
|
|
203
|
+
|
|
169
204
|
You might have noticed that there is no argument `varlist` in PyProcessMacro. This is because the list of variables
|
|
170
205
|
is automatically inferred from the variable names given to x, y, m.
|
|
171
206
|
|
|
@@ -241,6 +276,48 @@ p = Process(data=df, model=13, x="Effort", y="Success", w="Motivation", z="Skill
|
|
|
241
276
|
p.summary()
|
|
242
277
|
````
|
|
243
278
|
|
|
279
|
+
### F. Choosing the covariance estimator
|
|
280
|
+
|
|
281
|
+
By default, the standard errors of the OLS outcome models use the standard (homoskedastic) estimator. The
|
|
282
|
+
`cov_type` argument selects a heteroskedasticity-consistent estimator instead: `"HC0"`, `"HC1"`, `"HC2"` or
|
|
283
|
+
`"HC3"`. `hc3=True` is shorthand for `cov_type="HC3"`, which is what the original Process macro uses when
|
|
284
|
+
`hc3=1` is specified. Logistic outcome models always use the inverse of the Hessian.
|
|
285
|
+
|
|
286
|
+
````python
|
|
287
|
+
p = Process(data=df, model=4, x="Effort", y="Success", m=["MediationSkills"], cov_type="HC3")
|
|
288
|
+
````
|
|
289
|
+
|
|
290
|
+
### G. Serial mediation (Model 6)
|
|
291
|
+
|
|
292
|
+
In Model 6 the mediators form a chain: each mediator depends on X and on the mediators before it, and Y depends
|
|
293
|
+
on X and on every mediator. Pass two to four mediators in causal order. PyProcessMacro reports the specific
|
|
294
|
+
indirect effect through every ordered subset of mediators (three paths for two mediators, seven for three,
|
|
295
|
+
fifteen for four), labelled by the path, plus the total and the pairwise contrasts when `total=True` and
|
|
296
|
+
`contrast=True`.
|
|
297
|
+
|
|
298
|
+
````python
|
|
299
|
+
p = Process(data=df, model=6, x="Effort", y="Success", m=["Attention", "MediationSkills"], total=True)
|
|
300
|
+
p.summary()
|
|
301
|
+
````
|
|
302
|
+
|
|
303
|
+
Model 6 has no moderators, so the spotlight, floodlight and plotting methods do not apply to it. Its estimates are
|
|
304
|
+
checked against products of statsmodels coefficients and against an independent resampler; no PROCESS output for
|
|
305
|
+
Model 6 is part of the test fixtures yet, so a comparison file generated with PROCESS 2.16 would be a welcome
|
|
306
|
+
contribution.
|
|
307
|
+
|
|
308
|
+
### H. Effect sizes for the indirect effect
|
|
309
|
+
|
|
310
|
+
With `effsize=True`, PyProcessMacro also reports the partially standardized indirect effect (the indirect effect
|
|
311
|
+
divided by the standard deviation of Y) and the completely standardized indirect effect (further multiplied by the
|
|
312
|
+
standard deviation of X), each with a bootstrap confidence interval computed by standardizing within every resample,
|
|
313
|
+
as PROCESS does. The option applies to unmoderated indirect paths with a continuous outcome, that is Models 4 and 6
|
|
314
|
+
with `logit=False`.
|
|
315
|
+
|
|
316
|
+
````python
|
|
317
|
+
p = Process(data=df, model=4, x="Effort", y="Success", m=["MediationSkills"], effsize=True)
|
|
318
|
+
p.indirect_model.effect_size_summary()
|
|
319
|
+
````
|
|
320
|
+
|
|
244
321
|
## 2. Accessing the estimation results
|
|
245
322
|
|
|
246
323
|
After the `Process` object is initialized, you are not limited to printing the summary. PyProcessMacro implements the
|
|
@@ -338,6 +415,28 @@ Note that the methods are called from the `indirect_model` object! If you call `
|
|
|
338
415
|
error.
|
|
339
416
|
|
|
340
417
|
|
|
418
|
+
### E. Diagnostics and custom tests with statsmodels
|
|
419
|
+
|
|
420
|
+
Each outcome model can be handed to [statsmodels](https://www.statsmodels.org), which refits the same design
|
|
421
|
+
matrix with the same covariance estimator and returns the statsmodels results object. From there you get
|
|
422
|
+
`summary()`, custom contrasts with `t_test()` and `wald_test()`, heteroskedasticity and influence diagnostics,
|
|
423
|
+
variance inflation factors, prediction intervals, and the table formatters that accept statsmodels results.
|
|
424
|
+
statsmodels is optional: install it with `pip install pyprocessmacro[statsmodels]`.
|
|
425
|
+
|
|
426
|
+
````python
|
|
427
|
+
p = Process(data=df, model=7, x="Effort", y="Success", w="Motivation", m=["MediationSkills"], suppr_init=True)
|
|
428
|
+
|
|
429
|
+
fit = p.outcome_models["Success"].to_statsmodels() # a statsmodels RegressionResults
|
|
430
|
+
print(fit.summary())
|
|
431
|
+
fit.t_test("Effort + MediationSkills = 0")
|
|
432
|
+
|
|
433
|
+
fits = p.to_statsmodels() # every outcome model, keyed by outcome name
|
|
434
|
+
````
|
|
435
|
+
|
|
436
|
+
For a different question, statsmodels also ships `statsmodels.stats.mediation.Mediation`, Imai-style causal
|
|
437
|
+
mediation with a sensitivity analysis; it estimates a different quantity and is a useful cross-check rather than
|
|
438
|
+
a replacement for the PROCESS approach.
|
|
439
|
+
|
|
341
440
|
## 3. Spotlight and Floodlight Analysis
|
|
342
441
|
|
|
343
442
|
### A. Compute direct/indirect effects for specific values (spotlight analysis)
|
|
@@ -568,6 +667,32 @@ g = p.plot_conditional_indirect_effects(med_name="MediationSkills", x="Motivatio
|
|
|
568
667
|
````
|
|
569
668
|

|
|
570
669
|
|
|
670
|
+
## 6. Standardized results: tidy(), glance() and augment()
|
|
671
|
+
|
|
672
|
+
Every table PyProcessMacro prints is also available in a standardized form, modelled on R's broom package:
|
|
673
|
+
|
|
674
|
+
* `tidy()` returns one long DataFrame with one row per estimate and fixed column names: `component`
|
|
675
|
+
(`outcome`, `direct`, `indirect`, `total`, `contrast`, or `index_mm`, `index_pmm`, `index_mmm`, `index_cmm`),
|
|
676
|
+
`outcome`, `term`, `moderator`, one column per moderator of the model holding the spotlight value the row is
|
|
677
|
+
evaluated at, then `estimate`, `std_error`, `statistic`, `p_value`, `conf_low`, `conf_high`, `method`,
|
|
678
|
+
`conf_level` and `n_boot`. Pass `component=` to keep one kind of row.
|
|
679
|
+
* `glance()` returns one row of fit statistics per outcome model, including the log-likelihood, AIC and BIC.
|
|
680
|
+
* `augment()` returns the analysis data with `.fitted_<outcome>` and `.resid_<outcome>` columns per outcome model.
|
|
681
|
+
|
|
682
|
+
````python
|
|
683
|
+
p = Process(data=df, model=7, x="Effort", y="Success", w="Motivation", m=["MediationSkills"], suppr_init=True)
|
|
684
|
+
|
|
685
|
+
estimates = p.tidy() # every estimate
|
|
686
|
+
indirect = p.tidy("indirect") # only the conditional indirect effects
|
|
687
|
+
fit = p.glance() # R², AIC, BIC, ... per outcome model
|
|
688
|
+
residuals = p.augment(outcome="Success") # fitted values and residuals of the outcome model
|
|
689
|
+
|
|
690
|
+
estimates.to_csv("process_model7.csv", index=False)
|
|
691
|
+
````
|
|
692
|
+
|
|
693
|
+
`summary()` returns the text it prints, so `report = p.summary()` keeps a copy, and a `Process` object displayed at
|
|
694
|
+
the end of a notebook cell shows its tables as HTML.
|
|
695
|
+
|
|
571
696
|
# 7. About
|
|
572
697
|
PyProcessMacro was developed by Quentin André during his PhD in Marketing at INSEAD Business School, France.
|
|
573
698
|
|