Skip to contents

model_parameters() and compare_parameters() are functions that return a data frame of model summaries in a consistent way. The printed table of those summaries is formatted to make the output more readable and removes or collapses redundant columns, to get a compact and yet comprehensive summary table. (N.B. for developers: the function standardize_names() standardizes the column names, so column names are consistent and the same for any model object, also in broom style, which makes it easy to build your packages on top of the parameters package.)

The default print-methods for model_parameters() and compare_parameters() allows the user to modify the layout and style of the output.

Summaries for a single model

In the following examples for model_parameters(), which returns tabular output for single models, are shown.

Pretty parameter names formatting

By default, the argument pretty_names is TRUE, meaning that parameter names are formatted to make them more “human readable”, i.e. factor levels are separated from the variable names, interactions are denoted by * etc.

library(parameters)
data(iris)
model <- lm(Sepal.Length ~ Species * Petal.Length, data = iris)
model_parameters(model)
#> Parameter                           | Coefficient |   SE |         95% CI | t(144) |      p
#> -------------------------------------------------------------------------------------------
#> (Intercept)                         |        4.21 | 0.41 | [ 3.41,  5.02] |  10.34 | < .001
#> Species [versicolor]                |       -1.81 | 0.60 | [-2.99, -0.62] |  -3.02 | 0.003 
#> Species [virginica]                 |       -3.15 | 0.63 | [-4.41, -1.90] |  -4.97 | < .001
#> Petal Length                        |        0.54 | 0.28 | [ 0.00,  1.09] |   1.96 | 0.052 
#> Species [versicolor] * Petal Length |        0.29 | 0.30 | [-0.30,  0.87] |   0.97 | 0.334 
#> Species [virginica] * Petal Length  |        0.45 | 0.29 | [-0.12,  1.03] |   1.56 | 0.120

mp <- model_parameters(model)
print(mp, pretty_names = FALSE)
#> Parameter                      | Coefficient |   SE |         95% CI | t(144) |      p
#> --------------------------------------------------------------------------------------
#> (Intercept)                    |        4.21 | 0.41 | [ 3.41,  5.02] |  10.34 | < .001
#> Speciesversicolor              |       -1.81 | 0.60 | [-2.99, -0.62] |  -3.02 | 0.003 
#> Speciesvirginica               |       -3.15 | 0.63 | [-4.41, -1.90] |  -4.97 | < .001
#> Petal.Length                   |        0.54 | 0.28 | [ 0.00,  1.09] |   1.96 | 0.052 
#> Speciesversicolor:Petal.Length |        0.29 | 0.30 | [-0.30,  0.87] |   0.97 | 0.334 
#> Speciesvirginica:Petal.Length  |        0.45 | 0.29 | [-0.12,  1.03] |   1.56 | 0.120

Splitting model components

Again by default, the argument split_components is TRUE, which means that models with multiple components like fixed and random effects, count and zero-inflated part etc. are split into separate tables in the output.

library(glmmTMB)
data("Salamanders")
model <- glmmTMB(count ~ spp + mined + (1 | site),
                 ziformula = ~spp + mined,
                 family = nbinom2(), 
                 data = Salamanders)
model_parameters(model)
#> # Fixed Effects (Count Model)
#> 
#> Parameter   | Log-Mean |   SE |        95% CI |     z |      p
#> --------------------------------------------------------------
#> (Intercept) |    -0.61 | 0.41 | [-1.40, 0.18] | -1.51 | 0.132 
#> spp [PR]    |    -0.96 | 0.64 | [-2.23, 0.30] | -1.50 | 0.134 
#> spp [DM]    |     0.17 | 0.24 | [-0.29, 0.63] |  0.73 | 0.468 
#> spp [EC-A]  |    -0.39 | 0.34 | [-1.06, 0.28] | -1.13 | 0.258 
#> spp [EC-L]  |     0.49 | 0.24 | [ 0.02, 0.96] |  2.05 | 0.041 
#> spp [DES-L] |     0.59 | 0.23 | [ 0.14, 1.04] |  2.59 | 0.010 
#> spp [DF]    |    -0.11 | 0.24 | [-0.59, 0.36] | -0.46 | 0.642 
#> mined [no]  |     1.43 | 0.37 | [ 0.71, 2.15] |  3.90 | < .001
#> 
#> # Fixed Effects (Zero-Inflated Model)
#> 
#> Parameter   | Log-Odds |   SE |         95% CI |     z |      p
#> ---------------------------------------------------------------
#> (Intercept) |     0.91 | 0.63 | [-0.32,  2.14] |  1.45 | 0.147 
#> spp [PR]    |     1.16 | 1.33 | [-1.45,  3.78] |  0.87 | 0.384 
#> spp [DM]    |    -0.94 | 0.80 | [-2.51,  0.63] | -1.17 | 0.241 
#> spp [EC-A]  |     1.04 | 0.71 | [-0.36,  2.44] |  1.46 | 0.144 
#> spp [EC-L]  |    -0.56 | 0.73 | [-1.99,  0.86] | -0.77 | 0.439 
#> spp [DES-L] |    -0.89 | 0.75 | [-2.37,  0.58] | -1.19 | 0.236 
#> spp [DF]    |    -2.54 | 2.18 | [-6.82,  1.74] | -1.16 | 0.244 
#> mined [no]  |    -2.56 | 0.60 | [-3.75, -1.38] | -4.24 | < .001
#> 
#> # Random Effects Variances
#> 
#> Parameter            | Coefficient |       95% CI
#> -------------------------------------------------
#> SD (Intercept: site) |        0.38 | [0.17, 0.87]
#> SD (Residual)        |        1.51 | [0.93, 2.46]

Redundant columns are removed. The related model component is shown as table header. However, you can also return a single table:

mp <- model_parameters(model)
print(mp, split_component = FALSE)
#> # Fixed Effects
#> 
#> Parameter            | Coefficient |   SE |         95% CI |     z |      p | Effects |     Component
#> -----------------------------------------------------------------------------------------------------
#> (Intercept)          |       -0.61 | 0.41 | [-1.40,  0.18] | -1.51 | 0.132  |   fixed |   conditional
#> spp [PR]             |       -0.96 | 0.64 | [-2.23,  0.30] | -1.50 | 0.134  |   fixed |   conditional
#> spp [DM]             |        0.17 | 0.24 | [-0.29,  0.63] |  0.73 | 0.468  |   fixed |   conditional
#> spp [EC-A]           |       -0.39 | 0.34 | [-1.06,  0.28] | -1.13 | 0.258  |   fixed |   conditional
#> spp [EC-L]           |        0.49 | 0.24 | [ 0.02,  0.96] |  2.05 | 0.041  |   fixed |   conditional
#> spp [DES-L]          |        0.59 | 0.23 | [ 0.14,  1.04] |  2.59 | 0.010  |   fixed |   conditional
#> spp [DF]             |       -0.11 | 0.24 | [-0.59,  0.36] | -0.46 | 0.642  |   fixed |   conditional
#> mined [no]           |        1.43 | 0.37 | [ 0.71,  2.15] |  3.90 | < .001 |   fixed |   conditional
#> (Intercept)          |        0.91 | 0.63 | [-0.32,  2.14] |  1.45 | 0.147  |   fixed | zero_inflated
#> sppPR                |        1.16 | 1.33 | [-1.45,  3.78] |  0.87 | 0.384  |   fixed | zero_inflated
#> sppDM                |       -0.94 | 0.80 | [-2.51,  0.63] | -1.17 | 0.241  |   fixed | zero_inflated
#> sppEC-A              |        1.04 | 0.71 | [-0.36,  2.44] |  1.46 | 0.144  |   fixed | zero_inflated
#> sppEC-L              |       -0.56 | 0.73 | [-1.99,  0.86] | -0.77 | 0.439  |   fixed | zero_inflated
#> sppDES-L             |       -0.89 | 0.75 | [-2.37,  0.58] | -1.19 | 0.236  |   fixed | zero_inflated
#> sppDF                |       -2.54 | 2.18 | [-6.82,  1.74] | -1.16 | 0.244  |   fixed | zero_inflated
#> minedno              |       -2.56 | 0.60 | [-3.75, -1.38] | -4.24 | < .001 |   fixed | zero_inflated
#> SD (Intercept: site) |        0.38 |      | [ 0.17,  0.87] |       |        |  random |   conditional
#> SD (Residual)        |        1.51 |      | [ 0.93,  2.46] |       |        |  random |   conditional

Adding model summaries

A model summary can be added to the table when summary = TRUE in the call to model_parameters():

model <- lm(Sepal.Length ~ Species * Petal.Length, data = iris)
model_parameters(model, summary = TRUE)
#> Parameter                           | Coefficient |   SE |         95% CI | t(144) |      p
#> -------------------------------------------------------------------------------------------
#> (Intercept)                         |        4.21 | 0.41 | [ 3.41,  5.02] |  10.34 | < .001
#> Species [versicolor]                |       -1.81 | 0.60 | [-2.99, -0.62] |  -3.02 | 0.003 
#> Species [virginica]                 |       -3.15 | 0.63 | [-4.41, -1.90] |  -4.97 | < .001
#> Petal Length                        |        0.54 | 0.28 | [ 0.00,  1.09] |   1.96 | 0.052 
#> Species [versicolor] * Petal Length |        0.29 | 0.30 | [-0.30,  0.87] |   0.97 | 0.334 
#> Species [virginica] * Petal Length  |        0.45 | 0.29 | [-0.12,  1.03] |   1.56 | 0.120 
#> 
#> Model: Sepal.Length ~ Species * Petal.Length (150 Observations)
#> Residual standard deviation: 0.336 (df = 144)
#> R2: 0.840; adjusted R2: 0.835

Changing number of digits

digits changes the digits for coefficients, standard errors and statistics. ci_digits and p_digits are especially for the confidence intervals and p-values.

model <- lm(Sepal.Length ~ Species, data = iris)
model_parameters(model, digits = 4)
#> Parameter            | Coefficient |     SE |       95% CI |  t(147) |      p
#> -----------------------------------------------------------------------------
#> (Intercept)          |      5.0060 | 0.0728 | [4.86, 5.15] | 68.7616 | < .001
#> Species [versicolor] |      0.9300 | 0.1030 | [0.73, 1.13] |  9.0328 | < .001
#> Species [virginica]  |      1.5820 | 0.1030 | [1.38, 1.79] | 15.3655 | < .001

p-values can be displayed in exact, scientific notation if required.

model_parameters(model, p_digits = "scientific")
#> Parameter            | Coefficient |   SE |       95% CI | t(147) |            p
#> --------------------------------------------------------------------------------
#> (Intercept)          |        5.01 | 0.07 | [4.86, 5.15] |  68.76 | 1.13429e-113
#> Species [versicolor] |        0.93 | 0.10 | [0.73, 1.13] |   9.03 | 8.77019e-16 
#> Species [virginica]  |        1.58 | 0.10 | [1.38, 1.79] |  15.37 | 2.21482e-32

Fixing column widths

By default, the width of table columns is set to the minimum required width. This works well for models that produce just one table. However, for models with multiple components, where each component is shown as separate table, columns are possibly no longer aligned across tables. See the following example from a zero-inflated mixed model that has three components (fixed count, fixed zero-inflated, random effects):

data("Salamanders")
# we create very long parameter names for this predictor here
levels(Salamanders$spp) <- paste("long", levels(Salamanders$spp))

model <- glmmTMB(
 count ~ spp + mined + (1 | site),
 ziformula = ~mined,
 family = poisson(),
 data = Salamanders
)

# default printing
model_parameters(model) 
#> # Fixed Effects (Count Model)
#> 
#> Parameter        | Log-Mean |   SE |         95% CI |     z |      p
#> --------------------------------------------------------------------
#> (Intercept)      |    -0.36 | 0.28 | [-0.90,  0.18] | -1.30 | 0.194 
#> spp [long PR]    |    -1.27 | 0.24 | [-1.74, -0.80] | -5.27 | < .001
#> spp [long DM]    |     0.27 | 0.14 | [ 0.00,  0.54] |  1.95 | 0.051 
#> spp [long EC-A]  |    -0.57 | 0.21 | [-0.97, -0.16] | -2.75 | 0.006 
#> spp [long EC-L]  |     0.67 | 0.13 | [ 0.41,  0.92] |  5.20 | < .001
#> spp [long DES-L] |     0.63 | 0.13 | [ 0.38,  0.87] |  4.96 | < .001
#> spp [long DF]    |     0.12 | 0.15 | [-0.17,  0.40] |  0.78 | 0.435 
#> mined [no]       |     1.27 | 0.27 | [ 0.74,  1.80] |  4.72 | < .001
#> 
#> # Fixed Effects (Zero-Inflated Model)
#> 
#> Parameter   | Log-Odds |   SE |         95% CI |     z |      p
#> ---------------------------------------------------------------
#> (Intercept) |     0.79 | 0.27 | [ 0.26,  1.32] |  2.90 | 0.004 
#> mined [no]  |    -1.84 | 0.31 | [-2.46, -1.23] | -5.87 | < .001
#> 
#> # Random Effects Variances
#> 
#> Parameter            | Coefficient |       95% CI
#> -------------------------------------------------
#> SD (Intercept: site) |        0.33 | [0.18, 0.63]
#> SD (Residual)        |        1.00 |

The column_width argument can be used to either define the width of specific columns, or to fix column widths of the same columns across tables to have the same width. In the latter case, use column_width = "fixed" in the print() method.

mp <- model_parameters(model)
print(mp, column_width = "fixed")
#> # Fixed Effects (Count Model)
#> 
#> Parameter            | Log-Mean |   SE |         95% CI |     z |      p
#> ------------------------------------------------------------------------
#> (Intercept)          |    -0.36 | 0.28 | [-0.90,  0.18] | -1.30 | 0.194 
#> spp [long PR]        |    -1.27 | 0.24 | [-1.74, -0.80] | -5.27 | < .001
#> spp [long DM]        |     0.27 | 0.14 | [ 0.00,  0.54] |  1.95 | 0.051 
#> spp [long EC-A]      |    -0.57 | 0.21 | [-0.97, -0.16] | -2.75 | 0.006 
#> spp [long EC-L]      |     0.67 | 0.13 | [ 0.41,  0.92] |  5.20 | < .001
#> spp [long DES-L]     |     0.63 | 0.13 | [ 0.38,  0.87] |  4.96 | < .001
#> spp [long DF]        |     0.12 | 0.15 | [-0.17,  0.40] |  0.78 | 0.435 
#> mined [no]           |     1.27 | 0.27 | [ 0.74,  1.80] |  4.72 | < .001
#> 
#> # Fixed Effects (Zero-Inflated Model)
#> 
#> Parameter            | Log-Odds |   SE |         95% CI |     z |      p
#> ------------------------------------------------------------------------
#> (Intercept)          |     0.79 | 0.27 | [ 0.26,  1.32] |  2.90 | 0.004 
#> mined [no]           |    -1.84 | 0.31 | [-2.46, -1.23] | -5.87 | < .001
#> 
#> # Random Effects Variances
#> 
#> Parameter            | Coefficient |         95% CI
#> ---------------------------------------------------
#> SD (Intercept: site) |        0.33 |   [0.18, 0.63]
#> SD (Residual)        |        1.00 |

If column_width is a named vector, names are matched against column names, and those columns gain the specified minimum width.

print(mp, column_width = c(SE = 8, `95% CI` = 12, p = 7))
#> # Fixed Effects (Count Model)
#> 
#> Parameter        | Log-Mean |       SE |         95% CI |     z |       p
#> -------------------------------------------------------------------------
#> (Intercept)      |    -0.36 |     0.28 | [-0.90,  0.18] | -1.30 |   0.194
#> spp [long PR]    |    -1.27 |     0.24 | [-1.74, -0.80] | -5.27 |  < .001
#> spp [long DM]    |     0.27 |     0.14 | [ 0.00,  0.54] |  1.95 |   0.051
#> spp [long EC-A]  |    -0.57 |     0.21 | [-0.97, -0.16] | -2.75 |   0.006
#> spp [long EC-L]  |     0.67 |     0.13 | [ 0.41,  0.92] |  5.20 |  < .001
#> spp [long DES-L] |     0.63 |     0.13 | [ 0.38,  0.87] |  4.96 |  < .001
#> spp [long DF]    |     0.12 |     0.15 | [-0.17,  0.40] |  0.78 |   0.435
#> mined [no]       |     1.27 |     0.27 | [ 0.74,  1.80] |  4.72 |  < .001
#> 
#> # Fixed Effects (Zero-Inflated Model)
#> 
#> Parameter   | Log-Odds |       SE |         95% CI |     z |       p
#> --------------------------------------------------------------------
#> (Intercept) |     0.79 |     0.27 | [ 0.26,  1.32] |  2.90 |   0.004
#> mined [no]  |    -1.84 |     0.31 | [-2.46, -1.23] | -5.87 |  < .001
#> 
#> # Random Effects Variances
#> 
#> Parameter            | Coefficient |       95% CI
#> -------------------------------------------------
#> SD (Intercept: site) |        0.33 | [0.18, 0.63]
#> SD (Residual)        |        1.00 |

Group parameters

The groups argument can be used to group parameters in the table. groups must be a named list, where the names of the list elements equal the header of each group, while the values of the list elements equal the parameter names, or the position of the parameters in the table (data frame).

In the following example, we see the names of the parameters in the Parameter column, while the rownumbers indicate their position.

data(mtcars)
mtcars$cyl <- as.factor(mtcars$cyl)
mtcars$gear <- as.factor(mtcars$gear)
model <- lm(mpg ~ hp + gear * vs + cyl + drat, data = mtcars)

# don't select "Intercept" parameter
mp <- model_parameters(model, drop = "^\\(Intercept")

# inspect data frame
as.data.frame(mp)
#>   Parameter Coefficient    SE   CI CI_low CI_high     t df_error      p
#> 1        hp      -0.062 0.021 0.95  -0.11  -0.018 -2.91       22 0.0081
#> 2     gear4       3.100 4.339 0.95  -5.90  12.098  0.71       22 0.4825
#> 3     gear5       4.798 3.478 0.95  -2.42  12.011  1.38       22 0.1816
#> 4        vs       3.183 3.790 0.95  -4.68  11.042  0.84       22 0.4100
#> 5      cyl6      -2.466 2.210 0.95  -7.05   2.116 -1.12       22 0.2764
#> 6      cyl8       1.975 5.111 0.95  -8.63  12.575  0.39       22 0.7029
#> 7      drat       2.697 2.033 0.95  -1.52   6.913  1.33       22 0.1983
#> 8  gear4:vs      -2.897 4.665 0.95 -12.57   6.778 -0.62       22 0.5410
#> 9  gear5:vs       2.588 4.537 0.95  -6.82  11.998  0.57       22 0.5741

Now we create a group named "Engine", which encompasses the parameters "cyl6", "cyl8", "vs" and "hp". The "Interactions" group includes "gear4:vs" and "gear5:vs". The group "controls" has the parameters from rows 2, 3 and 7.

Note that the parameters in the table summary are re-ordered according to the order specified in groups.

# group parameters, either by parameter name or position
print(mp, groups = list("Engine" = c("cyl6", "cyl8", "vs", "hp"),
                        "Interactions" = c("gear4:vs", "gear5:vs"), 
                        "Controls" = c(2, 3, 7))) # gear 4 and 5, drat
#> Parameter        | Coefficient |   SE |          95% CI | t(22) |     p
#> -----------------------------------------------------------------------
#> Engine           |             |      |                 |       |      
#>   cyl [6]        |       -2.47 | 2.21 | [ -7.05,  2.12] | -1.12 | 0.276
#>   cyl [8]        |        1.97 | 5.11 | [ -8.63, 12.58] |  0.39 | 0.703
#>   vs             |        3.18 | 3.79 | [ -4.68, 11.04] |  0.84 | 0.410
#>   hp             |       -0.06 | 0.02 | [ -0.11, -0.02] | -2.91 | 0.008
#> Interactions     |             |      |                 |       |      
#>   gear [4] * vs  |       -2.90 | 4.67 | [-12.57,  6.78] | -0.62 | 0.541
#>   gear [5] * vs  |        2.59 | 4.54 | [ -6.82, 12.00] |  0.57 | 0.574
#> Controls         |             |      |                 |       |      
#>   gear [4]       |        3.10 | 4.34 | [ -5.90, 12.10] |  0.71 | 0.482
#>   gear [5]       |        4.80 | 3.48 | [ -2.42, 12.01] |  1.38 | 0.182
#>   drat           |        2.70 | 2.03 | [ -1.52,  6.91] |  1.33 | 0.198

If you prefer tables without vertical borders, use the sep argument to define the string that is used as border-separator. This argument is passed down to insight::export_table().

# group parameters, either by parameter name or position
print(mp, sep = "  ",
      groups = list("Engine" = c("cyl6", "cyl8", "vs", "hp"),
                    "Interactions" = c("gear4:vs", "gear5:vs"), 
                    "Controls" = c(2, 3, 7)))
#> Parameter         Coefficient    SE           95% CI  t(22)      p
#> ------------------------------------------------------------------
#> Engine                                                            
#>   cyl [6]               -2.47  2.21  [ -7.05,  2.12]  -1.12  0.276
#>   cyl [8]                1.97  5.11  [ -8.63, 12.58]   0.39  0.703
#>   vs                     3.18  3.79  [ -4.68, 11.04]   0.84  0.410
#>   hp                    -0.06  0.02  [ -0.11, -0.02]  -2.91  0.008
#> Interactions                                                      
#>   gear [4] * vs         -2.90  4.67  [-12.57,  6.78]  -0.62  0.541
#>   gear [5] * vs          2.59  4.54  [ -6.82, 12.00]   0.57  0.574
#> Controls                                                          
#>   gear [4]               3.10  4.34  [ -5.90, 12.10]   0.71  0.482
#>   gear [5]               4.80  3.48  [ -2.42, 12.01]   1.38  0.182
#>   drat                   2.70  2.03  [ -1.52,  6.91]   1.33  0.198

Summaries for multiple models

compare_parameters() (or its alias compare_models()) allows to create tables for multiple models, aligned side by side.

By default, estimates and confidence intervals are shown.

data(iris)
lm1 <- lm(Sepal.Length ~ Species, data = iris)
lm2 <- lm(Sepal.Length ~ Species + Petal.Length, data = iris)
lm3 <- lm(Sepal.Length ~ Species * Petal.Length, data = iris)
compare_parameters(lm1, lm2, lm3)
#> Parameter                           |               lm1 |                  lm2 |                  lm3
#> -----------------------------------------------------------------------------------------------------
#> (Intercept)                         | 5.01 (4.86, 5.15) |  3.68 ( 3.47,  3.89) |  4.21 ( 3.41,  5.02)
#> Species (versicolor)                | 0.93 (0.73, 1.13) | -1.60 (-1.98, -1.22) | -1.81 (-2.99, -0.62)
#> Species (virginica)                 | 1.58 (1.38, 1.79) | -2.12 (-2.66, -1.58) | -3.15 (-4.41, -1.90)
#> Petal Length                        |                   |  0.90 ( 0.78,  1.03) |  0.54 ( 0.00,  1.09)
#> Species (versicolor) * Petal Length |                   |                      |  0.29 (-0.30,  0.87)
#> Species (virginica) * Petal Length  |                   |                      |  0.45 (-0.12,  1.03)
#> -----------------------------------------------------------------------------------------------------
#> Observations                        |               150 |                  150 |                  150

Changing style of column output

By default, estimates and confidence intervals are shown. Using style allows us to create different output, e.g. standard errors instead of confidence intervals, or including p-values.

compare_parameters(lm1, lm2, lm3, style = "se_p")
#> Parameter                           |            lm1 |             lm2 |             lm3
#> ----------------------------------------------------------------------------------------
#> (Intercept)                         | 5.01*** (0.07) |  3.68*** (0.11) |  4.21*** (0.41)
#> Species (versicolor)                | 0.93*** (0.10) | -1.60*** (0.19) |  -1.81** (0.60)
#> Species (virginica)                 | 1.58*** (0.10) | -2.12*** (0.27) | -3.15*** (0.63)
#> Petal Length                        |                |  0.90*** (0.06) |     0.54 (0.28)
#> Species (versicolor) * Petal Length |                |                 |     0.29 (0.30)
#> Species (virginica) * Petal Length  |                |                 |     0.45 (0.29)
#> ----------------------------------------------------------------------------------------
#> Observations                        |            150 |             150 |             150

Defining column names

The column names for the models are by default the objects’ names. You can define own names using the column_names argument.

compare_parameters(
  lm1, lm2, lm3,
  column_names = c("First Model", "Second Model", "Third Model")
)
#> Parameter                           |       First Model |         Second Model |          Third Model
#> -----------------------------------------------------------------------------------------------------
#> (Intercept)                         | 5.01 (4.86, 5.15) |  3.68 ( 3.47,  3.89) |  4.21 ( 3.41,  5.02)
#> Species (versicolor)                | 0.93 (0.73, 1.13) | -1.60 (-1.98, -1.22) | -1.81 (-2.99, -0.62)
#> Species (virginica)                 | 1.58 (1.38, 1.79) | -2.12 (-2.66, -1.58) | -3.15 (-4.41, -1.90)
#> Petal Length                        |                   |  0.90 ( 0.78,  1.03) |  0.54 ( 0.00,  1.09)
#> Species (versicolor) * Petal Length |                   |                      |  0.29 (-0.30,  0.87)
#> Species (virginica) * Petal Length  |                   |                      |  0.45 (-0.12,  1.03)
#> -----------------------------------------------------------------------------------------------------
#> Observations                        |               150 |                  150 |                  150

Group parameters of multiple model tables

Grouping parameters works for compare_models() in the same way as shown above for model_parameters().

lm1 <- lm(Sepal.Length ~ Species + Petal.Length, data = iris)
lm2 <- lm(Sepal.Width ~ Species * Petal.Length, data = iris)

# remove intercept
cp <- compare_parameters(lm1, lm2, drop = "^\\(Intercept")

# look at parameters names, to know their names for "groups" argument
as.data.frame(cp)$Parameter
#> [1] "Species (versicolor)"                "Species (virginica)"                
#> [3] "Petal Length"                        "Species (versicolor) * Petal Length"
#> [5] "Species (virginica) * Petal Length"

# create groups. Interactions only present in 2nd model
print(cp, groups = list(Species = c("Species (versicolor)", 
                                    "Species (virginica)"),
                        Interactions = c("Species (versicolor) * Petal Length",
                                         "Species (virginica) * Petal Length"),
                        Controls = "Petal Length"))
#> Parameter                             |                  lm1 |                  lm2
#> -----------------------------------------------------------------------------------
#> Species                               |                      |                     
#>   Species (versicolor)                | -1.60 (-1.98, -1.22) | -1.69 (-2.80, -0.57)
#>   Species (virginica)                 | -2.12 (-2.66, -1.58) | -1.19 (-2.37, -0.01)
#> Interactions                          |                      |                     
#>   Species (versicolor) * Petal Length |                      | -0.01 (-0.56,  0.53)
#>   Species (virginica) * Petal Length  |                      | -0.15 (-0.69,  0.39)
#> Controls                              |                      |                     
#>   Petal Length                        |  0.90 ( 0.78,  1.03) |  0.39 (-0.13,  0.90)
#> -----------------------------------------------------------------------------------
#>   Observations                        |                  150 |                  150

Splitting wide tables into multiple table parts

For very wide tables that cannot be displayed properly, you can use the table_width argument in the print() method to split tables into multiple parts. table_width can be a numeric value, or "auto", indicating the width of the complete table. If table_width = "auto" and the table is wider than the current available width (i.e. line length) of the console (or any other source for textual output, like markdown files), the table is split into multiple parts. Else, if table_width is numeric and table rows are wider than table_width, the table is split into multiple parts.

data(iris)
lm1 <- lm(Sepal.Length ~ Species, data = iris)
lm2 <- lm(Sepal.Length ~ Species + Petal.Length, data = iris)
lm3 <- lm(Sepal.Length ~ Species * Petal.Length, data = iris)
lm4 <- lm(Sepal.Length ~ Species * Petal.Length + Petal.Width, data = iris)

# very wide table
compare_parameters(lm1, lm2, lm3, lm4)
#> Parameter                           |               lm1 |                  lm2 |                  lm3 |                  lm4
#> ----------------------------------------------------------------------------------------------------------------------------
#> (Intercept)                         | 5.01 (4.86, 5.15) |  3.68 ( 3.47,  3.89) |  4.21 ( 3.41,  5.02) |  4.21 ( 3.41,  5.02)
#> Species (versicolor)                | 0.93 (0.73, 1.13) | -1.60 (-1.98, -1.22) | -1.81 (-2.99, -0.62) | -1.80 (-2.99, -0.62)
#> Species (virginica)                 | 1.58 (1.38, 1.79) | -2.12 (-2.66, -1.58) | -3.15 (-4.41, -1.90) | -3.19 (-4.50, -1.88)
#> Petal Length                        |                   |  0.90 ( 0.78,  1.03) |  0.54 ( 0.00,  1.09) |  0.54 (-0.02,  1.09)
#> Species (versicolor) * Petal Length |                   |                      |  0.29 (-0.30,  0.87) |  0.28 (-0.30,  0.87)
#> Species (virginica) * Petal Length  |                   |                      |  0.45 (-0.12,  1.03) |  0.45 (-0.12,  1.03)
#> Petal Width                         |                   |                      |                      |  0.03 (-0.28,  0.34)
#> ----------------------------------------------------------------------------------------------------------------------------
#> Observations                        |               150 |                  150 |                  150 |                  150

# table split into two parts
tab <- compare_parameters(lm1, lm2, lm3, lm4)
print(tab, table_width = 80)
#> Parameter                           |               lm1 |                  lm2
#> ------------------------------------------------------------------------------
#> (Intercept)                         | 5.01 (4.86, 5.15) |  3.68 ( 3.47,  3.89)
#> Species (versicolor)                | 0.93 (0.73, 1.13) | -1.60 (-1.98, -1.22)
#> Species (virginica)                 | 1.58 (1.38, 1.79) | -2.12 (-2.66, -1.58)
#> Petal Length                        |                   |  0.90 ( 0.78,  1.03)
#> Species (versicolor) * Petal Length |                   |                     
#> Species (virginica) * Petal Length  |                   |                     
#> Petal Width                         |                   |                     
#> ------------------------------------------------------------------------------
#> Observations                        |               150 |                  150
#> 
#> Parameter                           |                  lm3 |                  lm4
#> ---------------------------------------------------------------------------------
#> (Intercept)                         |  4.21 ( 3.41,  5.02) |  4.21 ( 3.41,  5.02)
#> Species (versicolor)                | -1.81 (-2.99, -0.62) | -1.80 (-2.99, -0.62)
#> Species (virginica)                 | -3.15 (-4.41, -1.90) | -3.19 (-4.50, -1.88)
#> Petal Length                        |  0.54 ( 0.00,  1.09) |  0.54 (-0.02,  1.09)
#> Species (versicolor) * Petal Length |  0.29 (-0.30,  0.87) |  0.28 (-0.30,  0.87)
#> Species (virginica) * Petal Length  |  0.45 (-0.12,  1.03) |  0.45 (-0.12,  1.03)
#> Petal Width                         |                      |  0.03 (-0.28,  0.34)
#> ---------------------------------------------------------------------------------
#> Observations                        |                  150 |                  150

More advances tables and markdown / HTML formatting

The print_md() as well as print_html() functions can be used to create markdown (for knitting to PDF or Word) and HTML tables.

Meanwhile, there are a lot of additional packages that allow users to have even more flexibility regarding table layouts. One package we can recommend is the modelsummary package.