| Title: | Make Quick Descriptive Tables for Categorical Variables |
|---|---|
| Description: | Quickly make tables of descriptive statistics (i.e., counts, percentages, confidence intervals) for categorical variables. This package is designed to work in a Tidyverse pipeline, and consideration has been given to get results from R to Microsoft Word ® with minimal pain. |
| Authors: | Brad Cannell [aut, cre] |
| Maintainer: | Brad Cannell <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.2.0.9000 |
| Built: | 2026-09-19 11:07:57 UTC |
| Source: | https://github.com/brad-cannell/freqtables |
These helpers add intervals to freq_tbl() output, and are also used by
freq_table(). Both retain the package's Student-t convention:
SE = sqrt(p * (1 - p) / (N - 1)), with N - 1 degrees of freedom.
For within-group intervals, N is that group's denominator; for overall
intervals, N is the total input size. This is a compatibility convention,
not the usual normal-z binomial Wald interval.
wald_ci(.data, percent_ci = 95, se = FALSE, critical_value = FALSE) logit_ci(.data, percent_ci = 95, se = FALSE, critical_value = FALSE)wald_ci(.data, percent_ci = 95, se = FALSE, critical_value = FALSE) logit_ci(.data, percent_ci = 95, se = FALSE, critical_value = FALSE)
.data |
A frequency table from |
percent_ci |
Confidence level as a percentage, strictly between 0 and 100; default 95. Independent of the table's proportion/percentage scale. |
se |
Logical. Include standard errors? Default |
critical_value |
Logical. Include Student-t critical values in
|
wald_ci() returns p +/- t * SE without clipping to the unit interval.
logit_ci() transforms log(p / (1 - p)) +/- t * SE / (p * (1 - p))
back to the proportion scale with stats::plogis(). At p = 0 or 1,
logit bounds are missing (no continuity correction); Wald bounds equal p.
With N <= 1, SE, critical values, and both types of bounds are missing.
The input table with lcl/ucl, lcl_group/ucl_group,
and/or lcl_total/ucl_total for each proportion present.
Bounds and standard errors use the input scale; critical values do not
scale. Repeated calls replace interval/detail columns for the same
proportions, including removal of unrequested optional detail columns.
freq_tbl(mtcars, am) |> wald_ci() freq_tbl(mtcars, am) |> logit_ci(percent_ci = 99, se = TRUE) mtcars |> dplyr::group_by(cyl) |> freq_tbl(am, percent = TRUE, overall = TRUE) |> logit_ci(critical_value = TRUE)freq_tbl(mtcars, am) |> wald_ci() freq_tbl(mtcars, am) |> logit_ci(percent_ci = 99, se = TRUE) mtcars |> dplyr::group_by(cyl) |> freq_tbl(am, percent = TRUE, overall = TRUE) |> logit_ci(critical_value = TRUE)
Append a character column composed from existing table columns and literal
text. Works with compact proportions, percentages, grouped results, and
freq_test() output. Calculations retain full precision; rounding happens
only in the new display column.
freq_format(.data, recipe, name = NA, digits = NA)freq_format(.data, recipe, name = NA, digits = NA)
.data |
A data frame, commonly from |
recipe |
One quoted string containing column-name tokens and literal
text, e.g. |
name |
Name of the appended column. Default |
digits |
Nonnegative integer number of decimal places. Default |
The input data frame with one character column added or replaced.
freq_table(mtcars, am, percent = TRUE) |> freq_format("percent (lcl - ucl)", name = "percent_ci", digits = 2) mtcars |> dplyr::group_by(cyl) |> freq_table(am) |> freq_format("n: prop_group (lcl_group - ucl_group)", digits = 3)freq_table(mtcars, am, percent = TRUE) |> freq_format("percent (lcl - ucl)", name = "percent_ci", digits = 2) mtcars |> dplyr::group_by(cyl) |> freq_table(am) |> freq_format("n: prop_group (lcl_group - ucl_group)", digits = 3)
This is the code to create the study data - a simulated datas et that can be
used to demonstrate how to use the freqtables package.
freq_studyfreq_study
A data frame with 100 rows and 6 variables:
Participant's study identification number
Participant's age at the time of enrollment categorized as "Younger than 30" or "30 and Older"
Biological sex of the participant assigned at birth, female/male
Participant's bmi at date of enrollment categorized as "Underweight", "Normal", "Overweight", or "Obese"
Participant was exposed to a hypothetical risk factor of interest, Yes/No
Participant experienced a hypothetical outcome of interest, Yes/No
Combine freq_tbl() with logit_ci() or wald_ci(). Accept one outcome;
supply groups using dplyr::group_by(). Defaults are compact proportions
with confidence intervals. See vignette("migration") for the transition
from the old percentage-scale, two-variable interface.
freq_table( .data, .freq_var, ..., percent_ci = 95, ci_type = "logit", drop = FALSE, percent = FALSE, overall = FALSE, se = FALSE, critical_value = FALSE, generic_col_names = FALSE )freq_table( .data, .freq_var, ..., percent_ci = 95, ci_type = "logit", drop = FALSE, percent = FALSE, overall = FALSE, se = FALSE, critical_value = FALSE, generic_col_names = FALSE )
.data |
A local data frame or grouped data frame. Rowwise data is not
supported; call |
.freq_var |
One unquoted column name (or a string naming a column).
In a wrapper function, use |
... |
Reserved for detecting obsolete multiple-outcome calls and misspelled options. Must be empty; options must be named. |
percent_ci |
Confidence level as a percentage, strictly between 0 and 100; default 95. Independent of the table's proportion/percentage scale. |
ci_type |
Interval method: |
drop |
Logical. If |
percent |
Logical. If |
overall |
Logical. For grouped data, append |
se |
Logical. Include standard errors? Default |
critical_value |
Logical. Include Student-t critical values in
|
generic_col_names |
Logical. If |
An ungrouped tibble with the freq_tbl() columns plus confidence
limits. Classes are freq_table_one_way (no groups),
freq_table_two_way (one group), or freq_table_n_way (multiple
groups), together with freq_tbl and tibble classes.
freq_test() supports the first two cases; multiple grouping variables
do not imply a particular statistical test.
freq_table(mtcars, am) mtcars |> dplyr::group_by(cyl) |> freq_table(am) mtcars |> dplyr::group_by(cyl, vs) |> freq_table(am, ci_type = "wald", percent_ci = 90) freq_table(mtcars, am, percent = TRUE, overall = TRUE, se = TRUE, critical_value = TRUE, generic_col_names = TRUE)freq_table(mtcars, am) mtcars |> dplyr::group_by(cyl) |> freq_table(am) mtcars |> dplyr::group_by(cyl, vs) |> freq_table(am, ci_type = "wald", percent_ci = 90) freq_table(mtcars, am, percent = TRUE, overall = TRUE, se = TRUE, critical_value = TRUE, generic_col_names = TRUE)
Count one outcome within zero, one, or multiple groups supplied by
dplyr::group_by(). Each observation contributes once, including missing
outcomes and missing group values. Use dplyr::filter() before counting to
exclude missing observations explicitly.
freq_tbl( .data, .freq_var, ..., drop = FALSE, percent = FALSE, overall = FALSE, generic_col_names = FALSE )freq_tbl( .data, .freq_var, ..., drop = FALSE, percent = FALSE, overall = FALSE, generic_col_names = FALSE )
.data |
A local data frame or grouped data frame. Rowwise data is not
supported; call |
.freq_var |
One unquoted column name (or a string naming a column).
In a wrapper function, use |
... |
Reserved for detecting obsolete multiple-outcome calls and misspelled options. Must be empty; options must be named. |
drop |
Logical. If |
percent |
Logical. If |
overall |
Logical. For grouped data, append |
generic_col_names |
Logical. If |
An ungrouped tibble of class freq_tbl. Ungrouped defaults are
outcome, n, prop; grouped defaults are group columns, outcome,
n, n_group, prop_group. n_group is the total number of
observations in that group, across all outcome categories. Zero
denominators produce NA_real_ proportions. Variable types are preserved
unless generic headers are requested. Metadata retains the original total
for subsequent confidence-interval calculations even after filtering rows.
Analysis column names that collide with generated columns are rejected;
rename them before calling.
freq_tbl(mtcars, am) mtcars |> dplyr::group_by(cyl) |> freq_tbl(am) mtcars |> dplyr::group_by(cyl, vs) |> freq_tbl(am, percent = TRUE) freq_tbl(mtcars, am, generic_col_names = TRUE, overall = TRUE)freq_tbl(mtcars, am) mtcars |> dplyr::group_by(cyl) |> freq_tbl(am) mtcars |> dplyr::group_by(cyl, vs) |> freq_tbl(am, percent = TRUE) freq_tbl(mtcars, am, generic_col_names = TRUE, overall = TRUE)
Test equal category probabilities for an ungrouped table, or independence between one grouping variable and the outcome for a two-way table. Pearson's statistic is uncorrected (no Yates correction). For a two-way table with any expected count <= 5, also return Fisher's exact p-value and emit a message. The table is constructed from category identities, with omitted cells filled with zero, so row order and non-binary groups work.
freq_test(.data, ...) ## S3 method for class 'freq_table_one_way' freq_test(.data, ...) ## S3 method for class 'freq_table_two_way' freq_test(.data, ...) ## Default S3 method: freq_test(.data, ...)freq_test(.data, ...) ## S3 method for class 'freq_table_one_way' freq_test(.data, ...) ## S3 method for class 'freq_table_two_way' freq_test(.data, ...) ## Default S3 method: freq_test(.data, ...)
.data |
A complete |
... |
Reserved; no extra arguments are currently supported by either
method. Nonempty |
The input with expected counts, per-cell chi-square contributions,
the overall Pearson statistic, degrees of freedom, and
p_chi2_pearson. Two-way output also has n_col, r, c, and
(when expected counts are small) p_fisher. Omitted zero-count cells
contribute to the statistic even though they are absent from the output.
Fisher's exact calculation can fail for very large tables; the error
from stats::fisher.test() is propagated.
freq_table(mtcars, am) |> freq_test() mtcars |> dplyr::group_by(am) |> freq_table(cyl) |> freq_test() mtcars |> dplyr::group_by(cyl) |> freq_table(am, generic_col_names = TRUE) |> freq_test()freq_table(mtcars, am) |> freq_test() mtcars |> dplyr::group_by(am) |> freq_table(cyl) |> freq_test() mtcars |> dplyr::group_by(cyl) |> freq_table(am, generic_col_names = TRUE) |> freq_test()
Cross-tabulate two columns, with exposure in rows and outcome in columns.
Groups supplied by dplyr::group_by() become additional array dimensions
in the supplied order. Every input row contributes once, including missing
values; filter observations explicitly before counting to exclude them.
freq_xtab(.data, exposure, outcome, ..., margins = TRUE, drop = FALSE)freq_xtab(.data, exposure, outcome, ..., margins = TRUE, drop = FALSE)
.data |
A local data frame or grouped data frame. Rowwise data is not
supported; call |
exposure, outcome
|
Two distinct unquoted column names, or strings naming
columns. Forward columns in wrappers with |
... |
Must be empty. Options must be named; derived columns should be
created with |
margins |
Logical. If |
drop |
Logical. If |
A numeric matrix for ungrouped input, or a numeric array with
dimensions exposure, outcome, then each grouping variable. Dimension names
are the original column names. Factor categories follow level order;
other categories are sorted (character values in C-locale order), with
missing values last. Labels are character representations of categories;
ambiguous representations of distinct values are rejected. Missing labels
are actual NA_character_, distinct from literal strings such as "NA".
Select a missing category by position using which(is.na(dimnames(x)[[i]])).
Unobserved combinations, including empty group combinations, have zero
counts. Empty input retains factor levels when drop = FALSE; other axes
have length zero before margins. Thus empty ungrouped character input is
a 1-by-1 zero matrix with margins, or a 0-by-0 matrix without. A grouped
result with a zero-length grouping axis has no matrix slices. Singleton
dimensions are retained in the returned object; use drop = FALSE when
subsetting if those dimensions should remain.
freq_xtab(mtcars, vs, am) freq_xtab(mtcars, "vs", "am", margins = FALSE) mtcars |> dplyr::group_by(cyl) |> freq_xtab(vs, am) mtcars |> dplyr::group_by(cyl, gear) |> freq_xtab(vs, am, drop = TRUE)freq_xtab(mtcars, vs, am) freq_xtab(mtcars, "vs", "am", margins = FALSE) mtcars |> dplyr::group_by(cyl) |> freq_xtab(vs, am) mtcars |> dplyr::group_by(cyl, gear) |> freq_xtab(vs, am, drop = TRUE)
Given a tibble and a filter expression, get_group_n returns the group sample size formatted as "N = XXXX". Made to work in a dplyr pipeline, and used when creating tables for publications / reports.
get_group_n(.data, ...)get_group_n(.data, ...)
.data |
A local data frame or tibble, optionally grouped. Grouped input returns one label per retained group, in dplyr group order. |
... |
Zero or more dplyr::filter expressions, combined with AND. With no expressions, count all input rows. Missing logical results are excluded by filter(). Expressions may use dplyr data masking. |
A character vector of formatted counts. Ungrouped input returns one label, including "N = 0" when no observations remain.
library(dplyr) library(freqtables) data(mtcars) # Get sample size for cars with 4 cylinders mtcars %>% get_group_n(cyl == 4) #> [1] "N = 11"library(dplyr) library(freqtables) data(mtcars) # Get sample size for cars with 4 cylinders mtcars %>% get_group_n(cyl == 4) #> [1] "N = 11"