Migrating to the Compact Frequency-Table API

The development API changes defaults and grouping syntax. Update analysis scripts and recipes together. Use this guide when moving from version 0.1.1 or the earlier experimental branches.

Grouping and Named Options

An old call freq_table(mtcars, cyl, am) now produces an error showing the replacement. It is not a warning followed by a calculation.

mtcars |> group_by(cyl) |> freq_table(am)
#> # A tibble: 6 × 7
#>     cyl    am     n n_group prop_group lcl_group ucl_group
#>   <dbl> <dbl> <int>   <int>      <dbl>     <dbl>     <dbl>
#> 1     4     0     3      11      0.273    0.0716     0.646
#> 2     4     1     8      11      0.727    0.354      0.928
#> 3     6     0     4       7      0.571    0.150      0.909
#> 4     6     1     3       7      0.429    0.0906     0.850
#> 5     8     0    12      14      0.857    0.520      0.971
#> 6     8     1     2      14      0.143    0.0292     0.480

The one outcome is supplied as .freq_var. All subsequent options must be named, because ... is reserved for catching old calls and typos. For example, replace a positional confidence-level argument with percent_ci = 99. The experimental .drop and .percent names become drop and percent. There is one header option: generic_col_names; proposals such as col_headers are not aliases.

freq_tbl(mtcars, am, drop = TRUE, percent = TRUE)
#> # A tibble: 2 × 3
#>      am     n percent
#>   <dbl> <int>   <dbl>
#> 1     0    19    59.4
#> 2     1    13    40.6
freq_table(mtcars, am, percent_ci = 99, ci_type = "wald")
#> # A tibble: 2 × 5
#>      am     n  prop   lcl   ucl
#>   <dbl> <int> <dbl> <dbl> <dbl>
#> 1     0    19 0.594 0.352 0.836
#> 2     1    13 0.406 0.164 0.648

Output Names and Richer Tables

Previous result Current equivalent
var / cat Outcome-named column, or col / cat with generic headers
row_var / row_cat Group-named column, or group_01_col / group_01_cat
col_var / col_cat Outcome-named column, or col / cat
n_row n_group
percent_row prop_group, or percent_group with percent = TRUE
lcl_row / ucl_row lcl_group / ucl_group
Always-present overall/detail columns Request overall, se, and critical_value

All proportions, standard errors, and interval bounds default to the 0–1 scale. To request a rich, percentage-scale table with generic headers:

mtcars |> group_by(cyl) |>
  freq_table(am, percent = TRUE, overall = TRUE, se = TRUE,
             critical_value = TRUE, generic_col_names = TRUE)
#> # A tibble: 6 × 17
#>   group_01_col group_01_cat col   cat       n n_group percent_group n_total
#>   <chr>        <chr>        <chr> <chr> <int>   <int>         <dbl>   <int>
#> 1 cyl          4            am    0         3      11          27.3      32
#> 2 cyl          4            am    1         8      11          72.7      32
#> 3 cyl          6            am    0         4       7          57.1      32
#> 4 cyl          6            am    1         3       7          42.9      32
#> 5 cyl          8            am    0        12      14          85.7      32
#> 6 cyl          8            am    1         2      14          14.3      32
#> # ℹ 9 more variables: percent_total <dbl>, se_group <dbl>, t_crit_group <dbl>,
#> #   lcl_group <dbl>, ucl_group <dbl>, se_total <dbl>, t_crit_total <dbl>,
#> #   lcl_total <dbl>, ucl_total <dbl>

If downstream code still expects old names, rename explicitly. This is a compatibility mapping for a two-way result:

legacy <- mtcars |> group_by(cyl) |>
  freq_table(am, percent = TRUE, overall = TRUE, se = TRUE,
             critical_value = TRUE, generic_col_names = TRUE) |>
  rename(row_var = group_01_col, row_cat = group_01_cat,
         col_var = col, col_cat = cat, n_row = n_group,
         percent_row = percent_group, se_row = se_group,
         t_crit_row = t_crit_group, lcl_row = lcl_group, ucl_row = ucl_group)
legacy
#> # A tibble: 6 × 17
#>   row_var row_cat col_var col_cat     n n_row percent_row n_total percent_total
#>   <chr>   <chr>   <chr>   <chr>   <int> <int>       <dbl>   <int>         <dbl>
#> 1 cyl     4       am      0           3    11        27.3      32          9.38
#> 2 cyl     4       am      1           8    11        72.7      32         25   
#> 3 cyl     6       am      0           4     7        57.1      32         12.5 
#> 4 cyl     6       am      1           3     7        42.9      32          9.38
#> 5 cyl     8       am      0          12    14        85.7      32         37.5 
#> 6 cyl     8       am      1           2    14        14.3      32          6.25
#> # ℹ 8 more variables: se_row <dbl>, t_crit_row <dbl>, lcl_row <dbl>,
#> #   ucl_row <dbl>, se_total <dbl>, t_crit_total <dbl>, lcl_total <dbl>,
#> #   ucl_total <dbl>

Perform freq_test() before this renaming, because test methods need the current category schema and metadata. Update freq_format() recipes to reference the names actually in your table.

Statistical Continuity and Deliberate Changes

Ungrouped interval calculations preserve the t-based N - 1 convention. Grouped calculations now use n_group - 1 for both the standard-error denominator and degrees of freedom; the previous total-sample critical value is no longer used for a subgroup. Therefore, old grouped interval values cannot be recovered merely by renaming columns or multiplying by 100.

Logit bounds at p = 0 or 1 are missing without a continuity correction. Intervals for N <= 1 are missing. Wald bounds are not clipped. Explicit filter() calls determine how missing observations affect denominators.

Available Functions and Further Examples

The eight exported functions in this development version are:

Function Worked examples
freq_xtab() Contingency matrices and grouped arrays
freq_tbl() Counts and grouping
freq_table() Counts, intervals, and every option
wald_ci() Composable confidence intervals
logit_ci() Composable confidence intervals
freq_test() and its S3 methods Testing frequency tables
freq_format() Formatting results
get_group_n() Sample-size labels

A machine-checked function/argument coverage inventory is distributed at system.file("vignette-coverage.csv", package = "freqtables"). Every inventory row points to a source section and executable example chunk. The development check compares it with actual exported signatures and registered S3 methods.

freq_tables(), epidemiologic measures, and additional presentation formats remain separate proposals. They are not exported by this development version. Existing experimental source is preserved under dev/ or on its original branch.