ehs-risk-sem
Back to ehs-risk-sem

power

equicorrelated_matrix

equicorrelated_matrix(k: 'int', rho: 'float') -> 'np.ndarray'

Helper: a ``k x k`` correlation matrix with all off-diagonals equal to ``rho``.

Used by: study_01_sample_size.py

min_n_for_path_se

min_n_for_path_se(target_se: 'float', r_squared: 'float', vif: 'float', n_predictors: 'int') -> 'int'

Smallest N attaining a target standard error on a path coefficient.

Used by: study_01_sample_size.py

min_n_for_rmsea_power

min_n_for_rmsea_power(df: 'int', target_power: 'float' = 0.8, rmsea_null: 'float' = 0.05, rmsea_alt: 'float' = 0.08, alpha: 'float' = 0.05, n_max: 'int' = 200000) -> 'Optional[int]'

Smallest N reaching ``target_power`` for the test of close fit.

Implements the procedure described by MacCallum, Browne & Sugawara (1996): reject close fit when the chi-square exceeds the ``1 - alpha`` quantile of a noncentral chi-square with noncentrality ``(N-1)*df*rmsea_null^2``, and evaluate power against noncentrality ``(N-1)*df*rmsea_alt^2``.

Accuracy. The values returned here have been checked against the printed tables in MacCallum, Browne & Sugawara (1996), transcribed from the article itself rather than from a secondary reproduction; see ``tests/test_maccallum_1996_tables.py``, which pins all 52 cells of their Table 4 (this function), all 50 cells of their Table 5, and all 105 cells of their Table 2 (:func:`rmsea_power`). Power agrees to within 0.001, the precision at which the paper prints it. Sample sizes agree exactly at every df from 6 to 100 except for occasional one-unit differences, which are a property of their interval-halving search convention rather than of the procedure; the largest absolute disagreement anywhere in Table 4 is 6 observations at df = 2, where Nmin is 3,488. The underlying noncentral chi-square is separately validated against Monte Carlo in ``tests/test_special.py``.

One consequence worth knowing before quoting a cell: at df = 80 this function returns 153 where the published table prints 154. Power at N = 153 is 0.8002, so 153 is the smallest integer attaining the target, and both values are defensible. Quote whichever you can source.

Returns ``None`` if ``n_max`` is reached without attaining the target.

Used by: study_01_sample_size.py

min_n_to_distinguish

min_n_to_distinguish(beta_i: 'float', beta_j: 'float', predictor_corr: 'np.ndarray', r_squared: 'float', i: 'int' = 0, j: 'int' = 1, power: 'float' = 0.8, alpha: 'float' = 0.05, n_max: 'int' = 2000000) -> 'Optional[int]'

Sample size needed to detect that two coefficients differ.

Answers the question a reader actually has when a paper reports paths of 0.45 and 0.30 and describes the first as the dominant driver: is the sample large enough to distinguish them at all?

Uses a two-sided z test on the difference at the given power.

Used by: study_01_sample_size.py

noncentrality_from_rmsea

noncentrality_from_rmsea(rmsea: 'float', df: 'int', n: 'int') -> 'float'

Noncentrality parameter implied by an RMSEA value.

``lambda = (n - 1) * df * rmsea^2``, following MacCallum, Browne & Sugawara (1996).

path_se

path_se(r_squared: 'float', vif: 'float', n: 'int', n_predictors: 'int') -> 'float'

Asymptotic standard error of a standardized path coefficient.

``SE = sqrt((1 - R^2) * VIF / (n - k - 1))``

``VIF`` is the diagonal element of the inverse predictor correlation matrix. This expression conditions on the predictor correlations; in a latent-variable model those correlations are themselves estimated, so the real standard error is larger. ``simulations/study_01_sample_size.py`` measures the gap.

Used by: study_01_sample_size.py

rmsea_power

rmsea_power(df: 'int', n: 'int', rmsea_null: 'float' = 0.05, rmsea_alt: 'float' = 0.08, alpha: 'float' = 0.05) -> 'float'

Power of the test of close fit.

The null hypothesis is ``RMSEA <= rmsea_null``. The critical value is taken from the noncentral chi-square with the noncentrality implied by ``rmsea_null``, and power is evaluated under ``rmsea_alt``.

Handles both directions: when ``rmsea_alt > rmsea_null`` this is power to reject close fit for a model that is not close-fitting; when ``rmsea_alt < rmsea_null`` it is power for the test of not-close fit.

Used by: study_01_sample_size.py

se_of_difference

se_of_difference(predictor_corr: 'np.ndarray', r_squared: 'float', n: 'int', i: 'int', j: 'int') -> 'float'

Standard error of the difference between two coefficients in one model.

``Var(b_i - b_j) = (1 - R^2)/(n - k - 1) * [Rinv_ii + Rinv_jj - 2 Rinv_ij]``

Using the correct covariance term matters: when two predictors are positively correlated their coefficient estimates are negatively correlated, and ignoring that understates the uncertainty in their difference.

Used by: study_01_sample_size.py