Model-based continuous summary tables in R

library(spicy)

table_continuous_lm() is the model-based companion to table_continuous(). It fits one linear model per selected continuous outcome using lm(outcome ~ by, ...), then returns a compact reporting table. This makes it the better choice when you want to stay in a linear-model workflow, add heteroskedasticity-consistent standard errors, or apply case weights.

Basic usage

Use select for one or more continuous outcomes and by for the single predictor:

table_continuous_lm(
  sochealth,
  select = c(wellbeing_score, bmi, life_sat_health),
  by = sex
)
#> Continuous outcomes by Sex
#> 
#>  Variable                       │ M (Female)  M (Male)  Δ (Male - Female) 
#> ────────────────────────────────┼─────────────────────────────────────────
#>  WHO-5 wellbeing index (0-100)  │   67.16      71.05          3.89        
#>  Body mass index                │   25.69      26.20          0.51        
#>  Satisfaction with health (1-5) │    3.51       3.59          0.08        
#> 
#>  Variable                       │ 95% CI LL  95% CI UL      p   R²      n 
#> ────────────────────────────────┼─────────────────────────────────────────
#>  WHO-5 wellbeing index (0-100)  │   2.13       5.64     <.001  0.02  1200 
#>  Body mass index                │   0.09       0.93      .018  0.00  1188 
#>  Satisfaction with health (1-5) │   -0.06      0.22      .267  0.00  1192

For categorical predictors, the table reports estimated means by level. When the predictor is dichotomous, it can also show a single mean difference and confidence interval.

Robust standard errors

Use vcov = "HC*" when you want heteroskedasticity-consistent standard errors and tests:

table_continuous_lm(
  sochealth,
  select = c(wellbeing_score, bmi),
  by = sex,
  vcov = "HC3",
  statistic = TRUE
)
#> Continuous outcomes by Sex
#> 
#>  Variable                      │ M (Female)  M (Male)  Δ (Male - Female) 
#> ───────────────────────────────┼─────────────────────────────────────────
#>  WHO-5 wellbeing index (0-100) │   67.16      71.05          3.89        
#>  Body mass index               │   25.69      26.20          0.51        
#> 
#>  Variable                      │ 95% CI LL  95% CI UL   t        p   R²      n 
#> ───────────────────────────────┼───────────────────────────────────────────────
#>  WHO-5 wellbeing index (0-100) │   2.12       5.65     4.32  <.001  0.02  1200 
#>  Body mass index               │   0.09       0.93     2.38   .018  0.00  1188

Case weights

Use weights when you want weighted estimated means or slopes in the same model-based table:

table_continuous_lm(
  sochealth,
  select = c(wellbeing_score, bmi),
  by = education,
  weights = weight
)
#> Continuous outcomes by Highest education level
#> 
#>  Variable                      │ M (Lower secondary)  M (Upper secondary) 
#> ───────────────────────────────┼──────────────────────────────────────────
#>  WHO-5 wellbeing index (0-100) │        67.55                80.88        
#>  Body mass index               │        25.96                23.39        
#> 
#>  Variable                      │ M (Tertiary)      p   R²      n 
#> ───────────────────────────────┼─────────────────────────────────
#>  WHO-5 wellbeing index (0-100) │    66.52      <.001  0.19  1200 
#>  Body mass index               │    26.16      <.001  0.13  1188

This is often the most natural summary-table function when your reporting workflow already relies on weighted linear models.

Numeric predictors

If by is numeric, table_continuous_lm() reports the slope rather than group means:

table_continuous_lm(
  sochealth,
  select = c(wellbeing_score, bmi),
  by = age,
  vcov = "HC3",
  output = "long"
)
#>          variable                         label predictor_type predictor_label
#> 1 wellbeing_score WHO-5 wellbeing index (0-100)     continuous     Age (years)
#> 2             bmi               Body mass index     continuous     Age (years)
#>   level reference estimate_type emmean emmean_se emmean_ci_lower
#> 1  <NA>      <NA>         slope     NA        NA              NA
#> 2  <NA>      <NA>         slope     NA        NA              NA
#>   emmean_ci_upper   estimate estimate_se estimate_ci_lower estimate_ci_upper
#> 1              NA 0.04138096 0.030585451       -0.01862605        0.10138797
#> 2              NA 0.03508525 0.007455753        0.02045732        0.04971319
#>   test_type statistic df1  df2      p.value es_type    es_value          r2
#> 1         t  1.352962   1 1198 1.763230e-01      f2 0.001519732 0.001517426
#> 2         t  4.705796   1 1186 2.826189e-06      f2 0.019622500 0.019244867
#>         adj_r2    n sum_w
#> 1 0.0006839677 1200    NA
#> 2 0.0184179236 1188    NA

When you need the underlying returned data for further processing, use output = "data.frame" for the wide raw table or output = "long" for the analytic long table.

Publication-ready output

The function supports the same output formats as the other summary-table helpers, including tinytable, gt, flextable, excel, word, and clipboard.

pkgdown_dark_gt(
  table_continuous_lm(
    sochealth,
    select = c(wellbeing_score, bmi, life_sat_health),
    by = sex,
    vcov = "HC3",
    statistic = TRUE,
    output = "gt"
  )
)

See also