# Standardized Model Parameters

- Standardization by re-fitting the model
- Post-hoc standardization
- Smart standardization

The `model_parameters()` function (also accessible via the shortcut `parameters()`) can be used to calculate standardized model parameters, too, via the `standardize`-argument. There are different methods of standardizing model parameters: `"refit"`, `"posthoc"`, `"smart"` and `"basic"` (see `?effectsize::standardize_parameters` for further details).

## Standardization by re-fitting the model

`standardize = "refit"` is based on a complete model re-fit with a standardized version of data. Hence, this method is equal to standardizing the variables before fitting the model. It is the most accurate (Neter et al., 1989), but it is also the most computationally costly and long (especially for heavy models such as, for instance, for Bayesian models). This method is particularly recommended for complex models that include interactions or transformations (e.g., polynomial or spline terms).

When `standardize = "refit"`, `model_parameters()` internally calls `effectsize::standardize()` to standardize the data that was used to fit the model and updates the model with the standardized data. Note that `effectsize::standardize()` tries to detect which variables should be standardized and which not. For instance, having a `log(x)` in the model formula would exclude `x` from being standardized, because `x` might get negative values, and thus `log(x)` would no longer be defined. Factors will also be not standardized. Response variables will be standardized, if appropriate.

    library(lme4)
    data(iris)
    set.seed(1234)
    iris$grp <- as.factor(sample(1:3, nrow(iris), replace = TRUE))

    # fit example model
    model <- lme4::lmer(
      Sepal.Length ~ Species * Sepal.Width + Petal.Length + (1 | grp),
      data = iris
    )

    # classic model parameters
    model_parameters(model)

    #> Parameter                          | Coefficient |   SE |         95% CI | t(141) |      p
    #> ------------------------------------------------------------------------------------------
    #> (Intercept)                        |        1.55 | 0.40 | [ 0.77,  2.34] |   3.87 | < .001
    #> Species [versicolor]               |        0.41 | 0.55 | [-0.66,  1.49] |   0.75 | 0.453
    #> Species [virginica]                |       -0.41 | 0.58 | [-1.55,  0.73] |  -0.70 | 0.482
    #> Sepal.Width                        |        0.66 | 0.11 | [ 0.44,  0.88] |   5.83 | < .001
    #> Petal.Length                       |        0.82 | 0.07 | [ 0.69,  0.95] |  12.52 | < .001
    #> Species [versicolor] * Sepal.Width |       -0.48 | 0.19 | [-0.85, -0.12] |  -2.60 | 0.009
    #> Species [virginica] * Sepal.Width  |       -0.36 | 0.18 | [-0.71, -0.01] |  -1.99 | 0.046

    # standardized model parameters
    model_parameters(model, standardize = "refit")

    #> Parameter                          | Coefficient |   SE |         95% CI | t(141) |      p
    #> ------------------------------------------------------------------------------------------
    #> (Intercept)                        |        0.97 | 0.20 | [ 0.57,  1.37] |   4.74 | < .001
    #> Species [versicolor]               |       -1.29 | 0.26 | [-1.80, -0.77] |  -4.91 | < .001
    #> Species [virginica]                |       -1.81 | 0.34 | [-2.48, -1.15] |  -5.33 | < .001
    #> Sepal.Width                        |        0.35 | 0.06 | [ 0.23,  0.46] |   5.83 | < .001
    #> Petal.Length                       |        1.74 | 0.14 | [ 1.47,  2.02] |  12.52 | < .001
    #> Species [versicolor] * Sepal.Width |       -0.25 | 0.10 | [-0.45, -0.06] |  -2.60 | 0.009
    #> Species [virginica] * Sepal.Width  |       -0.19 | 0.09 | [-0.37,  0.00] |  -1.99 | 0.046

The second output is identical to following:

    # standardize continuous variables manually
    model2 <- lme4::lmer(
      scale(Sepal.Length) ~ Species * scale(Sepal.Width) + scale(Petal.Length) + (1 | grp),
      data = iris
    )
    model_parameters(model2)

    #> Parameter                          | Coefficient |   SE |         95% CI | t(141) |      p
    #> ------------------------------------------------------------------------------------------
    #> (Intercept)                        |        0.97 | 0.20 | [ 0.57,  1.37] |   4.74 | < .001
    #> Species [versicolor]               |       -1.29 | 0.26 | [-1.80, -0.77] |  -4.91 | < .001
    #> Species [virginica]                |       -1.81 | 0.34 | [-2.48, -1.15] |  -5.33 | < .001
    #> Sepal.Width                        |        0.35 | 0.06 | [ 0.23,  0.46] |   5.83 | < .001
    #> Petal.Length                       |        1.74 | 0.14 | [ 1.47,  2.02] |  12.52 | < .001
    #> Species [versicolor] * Sepal.Width |       -0.25 | 0.10 | [-0.45, -0.06] |  -2.60 | 0.009
    #> Species [virginica] * Sepal.Width  |       -0.19 | 0.09 | [-0.37,  0.00] |  -1.99 | 0.046

## Post-hoc standardization

`standardize = "posthoc"` aims at emulating the results obtained by `"refit"` without refitting the model. The coefficients are divided by the standard deviation of the outcome (which becomes their expression ‘unit’). Then, the coefficients related to numeric variables are additionally multiplied by the standard deviation of the related terms, so that they correspond to changes of 1 SD of the predictor (e.g., “a change in 1 SD of x is related to a change of 0.24 of the SD of y”). This does not apply to binary variables or factors, so the coefficients are still related to changes in levels.

This method is not accurate and tends to give aberrant results when interactions are specified. However, this method of standardization is the “classic” result obtained by many statistical packages when standardized coefficients are requested.

When `standardize = "posthoc"`, `model_parameters()` internally calls `effectsize::standardize_parameters(method = "posthoc")`. Test statistic and p-values are not affected, i.e. they are the same as if no standardization would be applied.

    model_parameters(model, standardize = "posthoc")

    #> Parameter                          | Std. Coef. |   SE |         95% CI | t(141) |      p
    #> -----------------------------------------------------------------------------------------
    #> (Intercept)                        |       0.00 | 0.00 | [ 0.00,  0.00] |   3.87 | < .001
    #> Species [versicolor]               |       0.50 | 0.66 | [-0.80,  1.79] |   0.75 | 0.453
    #> Species [virginica]                |      -0.49 | 0.70 | [-1.87,  0.88] |  -0.70 | 0.482
    #> Sepal.Width                        |       0.35 | 0.06 | [ 0.23,  0.46] |   5.83 | < .001
    #> Petal.Length                       |       1.74 | 0.14 | [ 1.47,  2.02] |  12.52 | < .001
    #> Species [versicolor] * Sepal.Width |      -0.25 | 0.10 | [-0.45, -0.06] |  -2.60 | 0.009
    #> Species [virginica] * Sepal.Width  |      -0.19 | 0.09 | [-0.37,  0.00] |  -1.99 | 0.046

`standardize = "basic"` also applies post-hoc standardization, however, factors are converted to numeric, which means that it also scales the coefficient by the standard deviation of model’s matrix’ parameter of factor levels (transformed to integers) or binary predictors.

    model_parameters(model, standardize = "basic")

    #> Parameter                          | Std. Coef. |   SE |         95% CI | t(141) |      p
    #> -----------------------------------------------------------------------------------------
    #> (Intercept)                        |       0.00 | 0.00 | [ 0.00,  0.00] |   3.87 | < .001
    #> Species [versicolor]               |       0.23 | 0.31 | [-0.38,  0.85] |   0.75 | 0.453
    #> Species [virginica]                |      -0.23 | 0.33 | [-0.88,  0.42] |  -0.70 | 0.482
    #> Sepal.Width                        |       0.35 | 0.06 | [ 0.23,  0.46] |   5.83 | < .001
    #> Petal.Length                       |       1.74 | 0.14 | [ 1.47,  2.02] |  12.52 | < .001
    #> Species [versicolor] * Sepal.Width |      -0.77 | 0.30 | [-1.35, -0.19] |  -2.60 | 0.009
    #> Species [virginica] * Sepal.Width  |      -0.61 | 0.31 | [-1.22, -0.01] |  -1.99 | 0.046

## Smart standardization

`standardize = "smart"` is similar to `standardize = "posthoc"` in that it does not involve model re-fitting. The difference is that the SD of the response is computed on the relevant section of the data. For instance, if a factor with 3 levels A (the intercept), B and C is entered as a predictor, the effect corresponding to B vs. A will be scaled by the variance of the response at the intercept only. As a results, the coefficients for effects of factors are similar to a Glass’ delta.

    model_parameters(model, standardize = "smart")

    #> Parameter                          | Std. Coef. |   SE |         95% CI | t(141) |      p
    #> -----------------------------------------------------------------------------------------
    #> (Intercept)                        |       0.00 | 0.00 | [ 0.00,  0.00] |   3.87 | < .001
    #> Species [versicolor]               |       1.17 | 1.56 | [-1.88,  4.22] |   0.75 | 0.453
    #> Species [virginica]                |      -1.16 | 1.65 | [-4.39,  2.07] |  -0.70 | 0.482
    #> Sepal.Width                        |       0.35 | 0.06 | [ 0.23,  0.46] |   5.83 | < .001
    #> Petal.Length                       |       1.74 | 0.14 | [ 1.47,  2.02] |  12.52 | < .001
    #> Species [versicolor] * Sepal.Width |      -1.13 | 0.43 | [-1.97, -0.28] |  -2.60 | 0.009
    #> Species [virginica] * Sepal.Width  |      -0.83 | 0.42 | [-1.65, -0.01] |  -1.99 | 0.046