Skip to contents

table_continuous() summarizes continuous variables either overall or by a categorical grouping variable. It is designed for readable summary tables in the console and for publication-ready outputs in rendered documents. When by is supplied, it can also add group-comparison tests, test statistics, and effect sizes.

Basic usage

Use select to choose the continuous variables you want to summarize:

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score, life_sat_health)
)
#> Descriptive statistics
#> 
#>  Variable                          M     SD     Min    Max    95% CI LL 
#> ────────────────────────────────┼────────────────────────────────────────
#>  Body mass index                 25.93   3.72  16.00   38.90    25.72   
#>  WHO-5 wellbeing index (0-100)   69.04  15.62  18.70  100.00    68.16   
#>  Satisfaction with health (1-5)   3.55   1.25   1.00    5.00     3.48   
#> 
#>  Variable                        95% CI UL   n   
#> ────────────────────────────────┼─────────────────
#>  Body mass index                   26.14    1188 
#>  WHO-5 wellbeing index (0-100)     69.93    1200 
#>  Satisfaction with health (1-5)     3.62    1192 
#> 
#> Missing values removed: bmi (12), life_sat_health (8).

If you omit select, table_continuous() scans the data frame and keeps numeric columns. Non-numeric columns are dropped silently; set verbose = TRUE to list them in a message:

table_continuous(sochealth)
#> Descriptive statistics
#> 
#>  Variable                                       M       SD       Min   
#> ────────────────────────────────────────────┼───────────────────────────
#>  Age (years)                                   49.26    14.70    25.00 
#>  Monthly household income (CHF)              3833.00  1394.58  1000.00 
#>  WHO-5 wellbeing index (0-100)                 69.04    15.62    18.70 
#>  Body mass index                               25.93     3.72    16.00 
#>  Political position (0 = left, 10 = right)      5.48     2.03     0.00 
#>  Satisfaction with health (1-5)                 3.55     1.25     1.00 
#>  Satisfaction with work (1-5)                   3.38     1.18     1.00 
#>  Satisfaction with relationships (1-5)          3.72     1.10     1.00 
#>  Satisfaction with standard of living (1-5)     3.40     1.16     1.00 
#>  Survey design weight                           1.00     0.41     0.29 
#> 
#>  Variable                                      Max    95% CI LL  95% CI UL 
#> ────────────────────────────────────────────┼───────────────────────────────
#>  Age (years)                                   75.00     48.43      50.10  
#>  Monthly household income (CHF)              7388.00   3754.01    3911.98  
#>  WHO-5 wellbeing index (0-100)                100.00     68.16      69.93  
#>  Body mass index                               38.90     25.72      26.14  
#>  Political position (0 = left, 10 = right)     10.00      5.36       5.60  
#>  Satisfaction with health (1-5)                 5.00      3.48       3.62  
#>  Satisfaction with work (1-5)                   5.00      3.31       3.45  
#>  Satisfaction with relationships (1-5)          5.00      3.66       3.79  
#>  Satisfaction with standard of living (1-5)     5.00      3.33       3.46  
#>  Survey design weight                           3.45      0.97       1.02  
#> 
#>  Variable                                     n   
#> ────────────────────────────────────────────┼──────
#>  Age (years)                                 1200 
#>  Monthly household income (CHF)              1200 
#>  WHO-5 wellbeing index (0-100)               1200 
#>  Body mass index                             1188 
#>  Political position (0 = left, 10 = right)   1185 
#>  Satisfaction with health (1-5)              1192 
#>  Satisfaction with work (1-5)                1192 
#>  Satisfaction with relationships (1-5)       1192 
#>  Satisfaction with standard of living (1-5)  1192 
#>  Survey design weight                        1200 
#> 
#> Missing values removed: bmi (12), political_position (15), life_sat_health (8), life_sat_work (8), life_sat_relationships (8), life_sat_standard (8).

Grouped summaries

Add by to summarize the same variables across categories. When by is supplied, a Welch-test p-value column is added automatically:

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score, life_sat_health),
  by = education
)
#> Descriptive statistics
#> 
#>  Variable                        Group              M     SD     Min    Max   
#> ────────────────────────────────┼──────────────────────────────────────────────
#>  Body mass index                 Lower secondary  28.09   3.47  18.20   38.90 
#>                                  Upper secondary  26.02   3.43  16.00   37.10 
#>                                  Tertiary         24.39   3.52  16.00   33.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)   Lower secondary  57.22  15.44  18.70   97.90 
#>                                  Upper secondary  68.97  13.62  26.70  100.00 
#>                                  Tertiary         76.85  13.23  40.40  100.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Lower secondary   2.71   1.20   1.00    5.00 
#>                                  Upper secondary   3.53   1.19   1.00    5.00 
#>                                  Tertiary          4.11   1.04   1.00    5.00 
#> 
#>  Variable                        Group            95% CI LL  95% CI UL   n  
#> ────────────────────────────────┼────────────────────────────────────────────
#>  Body mass index                 Lower secondary    27.66      28.51    260 
#>                                  Upper secondary    25.73      26.31    534 
#>                                  Tertiary           24.04      24.74    394 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)   Lower secondary    55.33      59.10    261 
#>                                  Upper secondary    67.82      70.12    539 
#>                                  Tertiary           75.55      78.15    400 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Lower secondary     2.57       2.86    259 
#>                                  Upper secondary     3.43       3.63    534 
#>                                  Tertiary            4.01       4.21    399 
#> 
#>  Variable                        Group              p   
#> ────────────────────────────────┼────────────────────────
#>  Body mass index                 Lower secondary  <.001 
#>                                  Upper secondary        
#>                                  Tertiary               
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)   Lower secondary  <.001 
#>                                  Upper secondary        
#>                                  Tertiary               
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Lower secondary  <.001 
#>                                  Upper secondary        
#>                                  Tertiary               
#> 
#> Missing values removed: bmi (12), life_sat_health (8).

This is the main pattern for reporting continuous variables across groups such as education, sex, treatment arm, or survey wave. Pass p_value = FALSE to suppress the test column and keep the output strictly descriptive.

If you want the same outcomes reported in a linear-model workflow, with heteroskedasticity-consistent or cluster-robust standard errors, case weights, or additive covariate adjustment, use table_continuous_lm() instead:

table_continuous_lm(
  sochealth,
  select = c(bmi, wellbeing_score, life_sat_health),
  by = education,
  vcov = "HC3"
)
#> Continuous outcomes by Highest education level
#> 
#>  Variable                        M (Lower secondary)  M (Upper secondary) 
#> ────────────────────────────────┼──────────────────────────────────────────
#>  Body mass index                        28.09                26.02        
#>  WHO-5 wellbeing index (0-100)          57.22                68.97        
#>  Satisfaction with health (1-5)          2.71                 3.53        
#> 
#>  Variable                        M (Tertiary)    p     R²    n   
#> ────────────────────────────────┼─────────────────────────────────
#>  Body mass index                    24.39      <.001  0.13  1188 
#>  WHO-5 wellbeing index (0-100)      76.85      <.001  0.21  1200 
#>  Satisfaction with health (1-5)      4.11      <.001  0.16  1192 
#> 
#> Note. Std. errors: heteroskedasticity-robust (HC3).

Add test statistics and effect sizes

Grouped tables can also report the test statistic and an effect size alongside the default p-value column:

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score, life_sat_health),
  by = education,
  statistic = TRUE,
  effect_size = "auto",
  effect_size_ci = TRUE
)
#> Descriptive statistics
#> 
#>  Variable                        Group              M     SD     Min    Max   
#> ────────────────────────────────┼──────────────────────────────────────────────
#>  Body mass index                 Lower secondary  28.09   3.47  18.20   38.90 
#>                                  Upper secondary  26.02   3.43  16.00   37.10 
#>                                  Tertiary         24.39   3.52  16.00   33.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)   Lower secondary  57.22  15.44  18.70   97.90 
#>                                  Upper secondary  68.97  13.62  26.70  100.00 
#>                                  Tertiary         76.85  13.23  40.40  100.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Lower secondary   2.71   1.20   1.00    5.00 
#>                                  Upper secondary   3.53   1.19   1.00    5.00 
#>                                  Tertiary          4.11   1.04   1.00    5.00 
#> 
#>  Variable                        Group            95% CI LL  95% CI UL   n  
#> ────────────────────────────────┼────────────────────────────────────────────
#>  Body mass index                 Lower secondary    27.66      28.51    260 
#>                                  Upper secondary    25.73      26.31    534 
#>                                  Tertiary           24.04      24.74    394 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)   Lower secondary    55.33      59.10    261 
#>                                  Upper secondary    67.82      70.12    539 
#>                                  Tertiary           75.55      78.15    400 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Lower secondary     2.57       2.86    259 
#>                                  Upper secondary     3.43       3.63    534 
#>                                  Tertiary            4.01       4.21    399 
#> 
#>  Variable                        Group                    Test             p   
#> ────────────────────────────────┼───────────────────────────────────────────────
#>  Body mass index                 Lower secondary  F(2, 654.48) = 87.96   <.001 
#>                                  Upper secondary                               
#>                                  Tertiary                                      
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)   Lower secondary  F(2, 638.59) = 144.35  <.001 
#>                                  Upper secondary                               
#>                                  Tertiary                                      
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Lower secondary  F(2, 652.08) = 118.74  <.001 
#>                                  Upper secondary                               
#>                                  Tertiary                                      
#> 
#>  Variable                        Group                      ES           
#> ────────────────────────────────┼─────────────────────────────────────────
#>  Body mass index                 Lower secondary  η² = 0.13 [0.10, 0.17] 
#>                                  Upper secondary                         
#>                                  Tertiary                                
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)   Lower secondary  η² = 0.21 [0.17, 0.25] 
#>                                  Upper secondary                         
#>                                  Tertiary                                
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Lower secondary  η² = 0.16 [0.13, 0.20] 
#>                                  Upper secondary                         
#>                                  Tertiary                                
#> 
#> Missing values removed: bmi (12), life_sat_health (8).

Use test = "student" for equal-variance parametric tests or test = "nonparametric" for rank-based comparisons:

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score),
  by = education,
  test = "nonparametric",
  statistic = TRUE,
  effect_size = "auto"
)
#> Descriptive statistics
#> 
#>  Variable                       Group              M     SD     Min    Max   
#> ───────────────────────────────┼──────────────────────────────────────────────
#>  Body mass index                Lower secondary  28.09   3.47  18.20   38.90 
#>                                 Upper secondary  26.02   3.43  16.00   37.10 
#>                                 Tertiary         24.39   3.52  16.00   33.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)  Lower secondary  57.22  15.44  18.70   97.90 
#>                                 Upper secondary  68.97  13.62  26.70  100.00 
#>                                 Tertiary         76.85  13.23  40.40  100.00 
#> 
#>  Variable                       Group            95% CI LL  95% CI UL   n  
#> ───────────────────────────────┼────────────────────────────────────────────
#>  Body mass index                Lower secondary    27.66      28.51    260 
#>                                 Upper secondary    25.73      26.31    534 
#>                                 Tertiary           24.04      24.74    394 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)  Lower secondary    55.33      59.10    261 
#>                                 Upper secondary    67.82      70.12    539 
#>                                 Tertiary           75.55      78.15    400 
#> 
#>  Variable                       Group                Test         p   
#> ───────────────────────────────┼───────────────────────────────────────
#>  Body mass index                Lower secondary  H(2) = 144.63  <.001 
#>                                 Upper secondary                       
#>                                 Tertiary                              
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)  Lower secondary  H(2) = 233.53  <.001 
#>                                 Upper secondary                       
#>                                 Tertiary                              
#> 
#>  Variable                       Group               ES     
#> ───────────────────────────────┼────────────────────────────
#>  Body mass index                Lower secondary  ε² = 0.12 
#>                                 Upper secondary            
#>                                 Tertiary                   
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)  Lower secondary  ε² = 0.19 
#>                                 Upper secondary            
#>                                 Tertiary                   
#> 
#> Missing values removed: bmi (12).

effect_size = "auto" selects the canonical measure for the chosen test and number of groups: Hedges’ g (parametric, 2 groups), eta-squared (parametric, 3+ groups), rank-biserial r (nonparametric, 2 groups), or epsilon-squared (nonparametric, 3+ groups). To pick a specific measure explicitly, pass its character name:

table_continuous(
  sochealth,
  select = wellbeing_score,
  by = sex,
  effect_size = "hedges_g",
  effect_size_ci = TRUE
)
#> Descriptive statistics
#> 
#>  Variable                       Group     M     SD     Min    Max    95% CI LL 
#> ───────────────────────────────┼────────────────────────────────────────────────
#>  WHO-5 wellbeing index (0-100)  Female  67.16  14.80  19.60  100.00    65.99   
#>                                 Male    71.05  16.23  18.70  100.00    69.73   
#> 
#>  Variable                       Group   95% CI UL   n     p   
#> ───────────────────────────────┼───────────────────────────────
#>  WHO-5 wellbeing index (0-100)  Female    68.33    620  <.001 
#>                                 Male      72.37    580        
#> 
#>  Variable                       Group              ES            
#> ───────────────────────────────┼──────────────────────────────────
#>  WHO-5 wellbeing index (0-100)  Female  g = -0.25 [-0.36, -0.14] 
#>                                 Male

Allowed values are "none" (default), "auto" (= legacy TRUE), "hedges_g", "eta_sq", "r_rb", and "epsilon_sq". Incompatible explicit choices (e.g. "eta_sq" with two groups, or "hedges_g" with test = "nonparametric") trigger an actionable error.

When you need the underlying columns for further processing, use output = "data.frame":

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score),
  by = education,
  statistic = TRUE,
  effect_size = "auto",
  output = "data.frame"
)
#>          variable                         label           group     mean
#> 1             bmi               Body mass index Lower secondary 28.08731
#> 2             bmi               Body mass index Upper secondary 26.01891
#> 3             bmi               Body mass index        Tertiary 24.39036
#> 4 wellbeing_score WHO-5 wellbeing index (0-100) Lower secondary 57.21571
#> 5 wellbeing_score WHO-5 wellbeing index (0-100) Upper secondary 68.96920
#> 6 wellbeing_score WHO-5 wellbeing index (0-100)        Tertiary 76.85250
#>          sd  min   max ci_lower ci_upper   n   test_type statistic df1      df2
#> 1  3.471744 18.2  38.9 27.66333 28.51129 260 welch_anova  87.95902   2 654.4758
#> 2  3.434736 16.0  37.1 25.72693 26.31090 534        <NA>        NA  NA       NA
#> 3  3.520150 16.0  33.0 24.04170 24.73901 394        <NA>        NA  NA       NA
#> 4 15.444587 18.7  97.9 55.33323 59.09819 261 welch_anova 144.35083   2 638.5873
#> 5 13.621193 26.7 100.0 67.81669 70.12172 539        <NA>        NA  NA       NA
#> 6 13.226818 40.4 100.0 75.55235 78.15265 400        <NA>        NA  NA       NA
#>        p.value es_type  es_value es_ci_lower es_ci_upper
#> 1 1.467916e-34  eta_sq 0.1307679  0.09667861   0.1654516
#> 2           NA    <NA>        NA          NA          NA
#> 3           NA    <NA>        NA          NA          NA
#> 4 1.888362e-52  eta_sq 0.2081970  0.16901207   0.2461732
#> 5           NA    <NA>        NA          NA          NA
#> 6           NA    <NA>        NA          NA          NA

Selecting variables

select supports tidyselect helpers:

table_continuous(
  sochealth,
  select = starts_with("life_sat"),
  by = sex
)
#> Descriptive statistics
#> 
#>  Variable                                    Group    M     SD   Min   Max  
#> ────────────────────────────────────────────┼────────────────────────────────
#>  Satisfaction with health (1-5)              Female  3.51  1.25  1.00  5.00 
#>                                              Male    3.59  1.25  1.00  5.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with work (1-5)                Female  3.32  1.17  1.00  5.00 
#>                                              Male    3.44  1.20  1.00  5.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with relationships (1-5)       Female  3.71  1.09  1.00  5.00 
#>                                              Male    3.74  1.10  1.00  5.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with standard of living (1-5)  Female  3.37  1.16  1.00  5.00 
#>                                              Male    3.42  1.17  1.00  5.00 
#> 
#>  Variable                                    Group   95% CI LL  95% CI UL   n  
#> ────────────────────────────────────────────┼───────────────────────────────────
#>  Satisfaction with health (1-5)              Female    3.41       3.61     616 
#>                                              Male      3.49       3.69     576 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with work (1-5)                Female    3.23       3.41     615 
#>                                              Male      3.34       3.54     577 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with relationships (1-5)       Female    3.62       3.79     615 
#>                                              Male      3.65       3.83     577 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with standard of living (1-5)  Female    3.28       3.46     615 
#>                                              Male      3.33       3.52     577 
#> 
#>  Variable                                    Group    p   
#> ────────────────────────────────────────────┼──────────────
#>  Satisfaction with health (1-5)              Female  .267 
#>                                              Male         
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with work (1-5)                Female  .073 
#>                                              Male         
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with relationships (1-5)       Female  .570 
#>                                              Male         
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with standard of living (1-5)  Female  .453 
#>                                              Male         
#> 
#> Missing values removed: life_sat_health (8), life_sat_work (8), life_sat_relationships (8), life_sat_standard (8).

For more programmatic selection, set regex = TRUE:

table_continuous(
  sochealth,
  select = "^life_sat",
  regex = TRUE,
  by = education,
  output = "data.frame"
)
#>                  variable                                      label
#> 1         life_sat_health             Satisfaction with health (1-5)
#> 2         life_sat_health             Satisfaction with health (1-5)
#> 3         life_sat_health             Satisfaction with health (1-5)
#> 4           life_sat_work               Satisfaction with work (1-5)
#> 5           life_sat_work               Satisfaction with work (1-5)
#> 6           life_sat_work               Satisfaction with work (1-5)
#> 7  life_sat_relationships      Satisfaction with relationships (1-5)
#> 8  life_sat_relationships      Satisfaction with relationships (1-5)
#> 9  life_sat_relationships      Satisfaction with relationships (1-5)
#> 10      life_sat_standard Satisfaction with standard of living (1-5)
#> 11      life_sat_standard Satisfaction with standard of living (1-5)
#> 12      life_sat_standard Satisfaction with standard of living (1-5)
#>              group     mean        sd min max ci_lower ci_upper   n   test_type
#> 1  Lower secondary 2.714286 1.2021575   1   5 2.567189 2.861382 259 welch_anova
#> 2  Upper secondary 3.533708 1.1853493   1   5 3.432943 3.634473 534        <NA>
#> 3         Tertiary 4.110276 1.0432216   1   5 4.007602 4.212950 399        <NA>
#> 4  Lower secondary 2.570881 1.1467994   1   5 2.431102 2.710660 261 welch_anova
#> 5  Upper secondary 3.422430 1.1037312   1   5 3.328691 3.516169 535        <NA>
#> 6         Tertiary 3.851010 1.0314174   1   5 3.749112 3.952909 396        <NA>
#> 7  Lower secondary 3.023077 1.2268891   1   5 2.873246 3.172908 260 welch_anova
#> 8  Upper secondary 3.743446 0.9645227   1   5 3.661453 3.825439 534        <NA>
#> 9         Tertiary 4.158291 0.9322485   1   5 4.066423 4.250159 398        <NA>
#> 10 Lower secondary 2.666667 1.1635489   1   5 2.524846 2.808487 261 welch_anova
#> 11 Upper secondary 3.387218 1.1065913   1   5 3.292970 3.481466 532        <NA>
#> 12        Tertiary 3.887218 0.9588582   1   5 3.792847 3.981589 399        <NA>
#>    statistic df1      df2      p.value
#> 1  118.73585   2 652.0775 1.063917e-44
#> 2         NA  NA       NA           NA
#> 3         NA  NA       NA           NA
#> 4  105.98821   2 651.9434 1.398117e-40
#> 5         NA  NA       NA           NA
#> 6         NA  NA       NA           NA
#> 7   82.35074   2 617.9668 1.969764e-32
#> 8         NA  NA       NA           NA
#> 9         NA  NA       NA           NA
#> 10 101.31672   2 648.7723 5.105889e-39
#> 11        NA  NA       NA           NA
#> 12        NA  NA       NA           NA

Use exclude when you want a broad selection with one or two explicit removals:

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score, life_sat_health, life_sat_work),
  exclude = "life_sat_work",
  by = sex
)
#> Descriptive statistics
#> 
#>  Variable                        Group     M     SD     Min    Max   
#> ────────────────────────────────┼─────────────────────────────────────
#>  Body mass index                 Female  25.69   3.78  16.00   38.90 
#>                                  Male    26.20   3.64  16.00   37.70 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)   Female  67.16  14.80  19.60  100.00 
#>                                  Male    71.05  16.23  18.70  100.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Female   3.51   1.25   1.00    5.00 
#>                                  Male     3.59   1.25   1.00    5.00 
#> 
#>  Variable                        Group   95% CI LL  95% CI UL   n     p   
#> ────────────────────────────────┼──────────────────────────────────────────
#>  Body mass index                 Female    25.39      25.98    616   .018 
#>                                  Male      25.90      26.50    572        
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)   Female    65.99      68.33    620  <.001 
#>                                  Male      69.73      72.37    580        
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Female     3.41       3.61    616   .267 
#>                                  Male       3.49       3.69    576        
#> 
#> Missing values removed: bmi (12), life_sat_health (8).

Handling missing values

Missing values can never enter a mean, so they are always excluded from each variable’s statistics. The table discloses the exclusion in a note rather than staying silent:

table_continuous(
  sochealth,
  select = c(bmi, life_sat_health)
)
#> Descriptive statistics
#> 
#>  Variable                          M     SD    Min    Max   95% CI LL 
#> ────────────────────────────────┼──────────────────────────────────────
#>  Body mass index                 25.93  3.72  16.00  38.90    25.72   
#>  Satisfaction with health (1-5)   3.55  1.25   1.00   5.00     3.48   
#> 
#>  Variable                        95% CI UL   n   
#> ────────────────────────────────┼─────────────────
#>  Body mass index                   26.14    1188 
#>  Satisfaction with health (1-5)     3.62    1192 
#> 
#> Missing values removed: bmi (12), life_sat_health (8).

Missing values in by are removed by default (drop_na = TRUE), and the removal is again disclosed rather than silent – here in the note (“Rows with missing income_group removed”) and in a warning:

table_continuous(
  sochealth,
  select = bmi,
  by = income_group
)
#> Warning: 18 observation(s) with NA in `income_group` were excluded.
#> Descriptive statistics
#> 
#>  Variable         Group           M     SD    Min    Max   95% CI LL 
#> ─────────────────┼────────────────────────────────────────────────────
#>  Body mass index  Low           26.58  3.94  16.00  38.90    26.08   
#>                   Lower middle  26.19  3.47  16.00  37.30    25.84   
#>                   Upper middle  25.66  3.89  16.00  37.70    25.24   
#>                   High          25.15  3.43  16.00  35.00    24.68   
#> 
#>  Variable         Group         95% CI UL   n     p   
#> ─────────────────┼─────────────────────────────────────
#>  Body mass index  Low             27.07    246  <.001 
#>                   Lower middle    26.53    385        
#>                   Upper middle    26.09    325        
#>                   High            25.61    214        
#> 
#> Missing values removed: bmi (12). Rows with missing income_group removed: 18.

Set drop_na = FALSE to display those rows as a dedicated “(Missing)” group instead. The group-comparison test and effect size still cover the observed groups only, matching table_categorical():

table_continuous(
  sochealth,
  select = bmi,
  by = income_group,
  drop_na = FALSE
)
#> Descriptive statistics
#> 
#>  Variable         Group           M     SD    Min    Max   95% CI LL 
#> ─────────────────┼────────────────────────────────────────────────────
#>  Body mass index  Low           26.58  3.94  16.00  38.90    26.08   
#>                   Lower middle  26.19  3.47  16.00  37.30    25.84   
#>                   Upper middle  25.66  3.89  16.00  37.70    25.24   
#>                   High          25.15  3.43  16.00  35.00    24.68   
#>                   (Missing)     25.83  4.08  18.50  31.80    23.80   
#> 
#>  Variable         Group         95% CI UL   n     p   
#> ─────────────────┼─────────────────────────────────────
#>  Body mass index  Low             27.07    246  <.001 
#>                   Lower middle    26.53    385        
#>                   Upper middle    26.09    325        
#>                   High            25.61    214        
#>                   (Missing)       27.86     18        
#> 
#> Missing values removed: bmi (12).

Custom labels

By default, table_continuous() labels each variable with its label attribute when one is present (e.g. data imported with haven), and with the column name otherwise – that is why the tables above read “Body mass index” rather than bmi. Use the labels argument, a named character vector keyed by column name, to override either. Only the listed columns are relabelled; the others keep their attribute label or column name:

table_continuous(
  sochealth,
  select = c(wellbeing_score, life_sat_health),
  by = sex,
  labels = c(wellbeing_score = "Well-being score (0-100)")
)
#> Descriptive statistics
#> 
#>  Variable                        Group     M     SD     Min    Max   
#> ────────────────────────────────┼─────────────────────────────────────
#>  Well-being score (0-100)        Female  67.16  14.80  19.60  100.00 
#>                                  Male    71.05  16.23  18.70  100.00 
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Female   3.51   1.25   1.00    5.00 
#>                                  Male     3.59   1.25   1.00    5.00 
#> 
#>  Variable                        Group   95% CI LL  95% CI UL   n     p   
#> ────────────────────────────────┼──────────────────────────────────────────
#>  Well-being score (0-100)        Female    65.99      68.33    620  <.001 
#>                                  Male      69.73      72.37    580        
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  Satisfaction with health (1-5)  Female     3.41       3.61    616   .267 
#>                                  Male       3.49       3.69    576        
#> 
#> Missing values removed: life_sat_health (8).

Display options

The printed ASCII table and every rendered output share the same formatting vocabulary as table_continuous_lm(); align, p_digits, and decimal_mark are also shared with table_categorical():

  • align = "decimal" (default) aligns numeric columns on the decimal mark, matching SPSS / SAS / LaTeX siunitx conventions. "center" and "right" are the alternatives.
  • p_digits = 3 (default, the APA standard) drives both the displayed precision of the p column and the small-p threshold: with p_digits = 4, the chunk below shows .0176 for BMI and <.0001 for the well-being score.
  • show_n = FALSE and ci = FALSE drop the corresponding columns (and the CI spanner / borders) structurally from every output; the underlying n and ci_lower / ci_upper are always present in output = "data.frame" / "long" for downstream code.
table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score),
  by = sex,
  ci = FALSE,
  show_n = FALSE,
  p_digits = 4
)
#> Descriptive statistics
#> 
#>  Variable                       Group     M     SD     Min    Max      p    
#> ───────────────────────────────┼─────────────────────────────────────────────
#>  Body mass index                Female  25.69   3.78  16.00   38.90   .0176 
#>                                 Male    26.20   3.64  16.00   37.70         
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)  Female  67.16  14.80  19.60  100.00  <.0001 
#>                                 Male    71.05  16.23  18.70  100.00         
#> 
#> Missing values removed: bmi (12).

Tidying for downstream pipelines

table_continuous() returns an object that can be coerced to a plain data.frame / tbl_df (stripping the spicy formatting attributes) or piped into broom::tidy() / broom::glance() for any downstream tidyverse stats workflow:

out <- table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score),
  by = sex
)
#> Descriptive statistics
#> 
#>  Variable                       Group     M     SD     Min    Max    95% CI LL 
#> ───────────────────────────────┼────────────────────────────────────────────────
#>  Body mass index                Female  25.69   3.78  16.00   38.90    25.39   
#>                                 Male    26.20   3.64  16.00   37.70    25.90   
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)  Female  67.16  14.80  19.60  100.00    65.99   
#>                                 Male    71.05  16.23  18.70  100.00    69.73   
#> 
#>  Variable                       Group   95% CI UL   n     p   
#> ───────────────────────────────┼───────────────────────────────
#>  Body mass index                Female    25.98    616   .018 
#>                                 Male      26.50    572        
#> ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
#>  WHO-5 wellbeing index (0-100)  Female    68.33    620  <.001 
#>                                 Male      72.37    580        
#> 
#> Missing values removed: bmi (12).

# Long descriptive rows: one per (variable x group) with broom-style
# columns (outcome, label, group, estimate = mean, std.error,
# conf.low / conf.high, n, min, max, sd).
broom::tidy(out)
#> # A tibble: 4 × 11
#>   outcome    label group estimate std.error conf.low conf.high     n   min   max
#>   <chr>      <chr> <chr>    <dbl>     <dbl>    <dbl>     <dbl> <int> <dbl> <dbl>
#> 1 bmi        Body… Fema…     25.7     0.152     25.4      26.0   616  16    38.9
#> 2 bmi        Body… Male      26.2     0.152     25.9      26.5   572  16    37.7
#> 3 wellbeing… WHO-… Fema…     67.2     0.594     66.0      68.3   620  19.6 100  
#> 4 wellbeing… WHO-… Male      71.0     0.674     69.7      72.4   580  18.7 100  
#> # ℹ 1 more variable: sd <dbl>

# One row per outcome with the omnibus test + effect-size summary
# (test_type, statistic, df, df.residual, p.value, es_type, es_value,
# es_ci_lower / es_ci_upper, n_total).
broom::glance(out)
#> # A tibble: 2 × 12
#>   outcome   label test_type statistic    df df.residual p.value es_type es_value
#>   <chr>     <chr> <chr>         <dbl> <dbl>       <dbl>   <dbl> <chr>      <dbl>
#> 1 bmi       Body… welch_t       -2.38 1184.          NA 1.76e-2 NA            NA
#> 2 wellbein… WHO-… welch_t       -4.33 1169.          NA 1.65e-5 NA            NA
#> # ℹ 3 more variables: es_ci_lower <dbl>, es_ci_upper <dbl>, n_total <int>

# Or just unbox to a plain data.frame (long-format underlying data)
head(as.data.frame(out))
#>          variable                         label  group     mean        sd  min
#> 1             bmi               Body mass index Female 25.68506  3.781113 16.0
#> 2             bmi               Body mass index   Male 26.19685  3.638092 16.0
#> 3 wellbeing_score WHO-5 wellbeing index (0-100) Female 67.16194 14.798488 19.6
#> 4 wellbeing_score WHO-5 wellbeing index (0-100)   Male 71.04879 16.227304 18.7
#>     max ci_lower ci_upper   n test_type statistic      df1 df2      p.value
#> 1  38.9 25.38588 25.98425 616   welch_t -2.377237 1184.497  NA 1.760093e-02
#> 2  37.7 25.89808 26.49563 572      <NA>        NA       NA  NA           NA
#> 3 100.0 65.99480 68.32907 620   welch_t -4.326141 1168.700  NA 1.647005e-05
#> 4 100.0 69.72540 72.37219 580      <NA>        NA       NA  NA           NA

Output formats

table_continuous() supports the same reporting-oriented outputs as table_categorical():

output value Returned object
"default" Styled ASCII console table
"data.frame" / "long" Plain data.frame with the underlying long-format rows (synonyms; pick whichever reads better in your code)
"tinytable" Formatted tinytable
"gt" Formatted gt table
"flextable" Formatted flextable
"excel" Written .xlsx file
"clipboard" Copied text table
"word" Written .docx file

output = "gt" produces a formatted gt table with APA-style borders and column spanners:

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score, life_sat_health),
  by = education,
  output = "gt"
)
Variable
Group
M
SD
Min
Max
95% CI
n
p
LL UL
Body mass index Lower secondary 28.09  3.47 18.20  38.90 27.66 28.51 260 <.001
Upper secondary 26.02  3.43 16.00  37.10 25.73 26.31 534      
Tertiary 24.39  3.52 16.00  33.00 24.04 24.74 394      
WHO-5 wellbeing index (0-100) Lower secondary 57.22 15.44 18.70  97.90 55.33 59.10 261 <.001
Upper secondary 68.97 13.62 26.70 100.00 67.82 70.12 539      
Tertiary 76.85 13.23 40.40 100.00 75.55 78.15 400      
Satisfaction with health (1-5) Lower secondary  2.71  1.20  1.00   5.00  2.57  2.86 259 <.001
Upper secondary  3.53  1.19  1.00   5.00  3.43  3.63 534      
Tertiary  4.11  1.04  1.00   5.00  4.01  4.21 399      

output = "tinytable" works well in Quarto and R Markdown documents:

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score, life_sat_health),
  by = education,
  output = "tinytable"
)
Variable Group M SD Min Max 95% CI n p
LL UL
Body mass index Lower secondary 28.09  3.47 18.20  38.90 27.66 28.51 260 <.001
Upper secondary 26.02  3.43 16.00  37.10 25.73 26.31 534      
Tertiary 24.39  3.52 16.00  33.00 24.04 24.74 394      
WHO-5 wellbeing index (0-100) Lower secondary 57.22 15.44 18.70  97.90 55.33 59.10 261 <.001
Upper secondary 68.97 13.62 26.70 100.00 67.82 70.12 539      
Tertiary 76.85 13.23 40.40 100.00 75.55 78.15 400      
Satisfaction with health (1-5) Lower secondary  2.71  1.20  1.00   5.00  2.57  2.86 259 <.001
Upper secondary  3.53  1.19  1.00   5.00  3.43  3.63 534      
Tertiary  4.11  1.04  1.00   5.00  4.01  4.21 399      

Export to Excel or Word

Use the same function to export the table directly:

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score, life_sat_health),
  by = education,
  output = "excel",
  excel_path = "table_continuous.xlsx"
)

table_continuous(
  sochealth,
  select = c(bmi, wellbeing_score, life_sat_health),
  by = education,
  output = "word",
  word_path = "table_continuous.docx"
)

See also