tb() builds a frequency table for one variable, or a cross-tabulation of
two, with optional percentages, an association test, and crude effect
measures (PR, RR, or OR). Put the exposure first (rows) and the outcome
second (columns); a numeric first variable is summarised as mean (SD) or
median (IQR) within each outcome group. For many variables at once use
table1(); for adjusted estimates use regtab().
Usage
tb(
data,
...,
m = FALSE,
miss = FALSE,
d = 1,
big_mark = "",
decimal_mark = ".",
style = "n_pct",
style.rp = "{rp} ({lower} - {upper})",
style.or = "{or} ({lower} - {upper})",
test = FALSE,
subset = NULL,
strat = NULL,
rp = FALSE,
or = FALSE,
ref = NULL,
conf.level = 0.95,
var.type = NULL,
summary = "auto",
flags = NULL,
labels = NULL,
measure = NULL,
design = NULL
)Arguments
- data
A data frame, or a single vector to tabulate on its own.
- ...
One or two variables to tabulate: bare names, strings, or tidyselect expressions such as
all_of(v). The first becomes the rows and the second the columns. Terse flags such asroworormay follow; see Terse flags.- m
Deprecated; use
missinstead.- miss
Logical. If
TRUE, show missing values as their own row and column. Same as themissflag.- d
Integer. Decimal places for percentages and continuous summaries. Effect measures always use two decimals.
- big_mark
String inserted between every three digits, e.g.
","prints4391as4,391.- decimal_mark
String used as the decimal point, e.g.
",". Must differ frombig_mark.- style
String. How counts and percentages are shown:
"n_pct"(12 (5.0%)),"pct_n"(5.0% (12)), or a template using{n}and{p}, such as"{n} [{p}%]".- style.rp
String template for prevalence and risk ratios, using
{rp},{lower}, and{upper}.- style.or
String template for odds ratios, using
{or},{lower}, and{upper}.- test
Logical or string.
TRUEadds a p-value from an automatically chosen test; or force"chisq","fisher", or"mcnemar". See Statistical methods for how the test is chosen.- subset
A logical expression evaluated in
datato keep only some rows, e.g.subset = age >= 65.- strat
A variable to stratify by: a bare name or string. The table is repeated within each stratum and, if an effect measure is requested, a Mantel-Haenszel pooled estimate is added.
- rp
Deprecated; use the
prflag ormeasure = "PR"instead.- or
Logical. If
TRUE, add odds ratios. Same as theorflag.- ref
Reference level of the row (exposure) variable for effect measures, given as a level name or its position. If
NULL, the first level is used and a note is printed.- conf.level
Number between 0 and 1. Confidence level for effect measure intervals.
- var.type
Force variable types:
"continuous"or"categorical", either one string for all variables or a named vector such asc(score = "continuous"). IfNULL, types are detected automatically (see Statistical methods).- summary
String. Summary for numeric variables:
"auto"chooses between"mean"(mean and SD) and"median"(median and IQR) based on sample size and skewness.- flags
Character vector of terse flags, e.g.
c("row", "or", "p"). The programmatic form of the bare flags in....- labels
Named character vector of display labels, e.g.
c(smoking = "Smoking status"). Variable labels already stored indataare used by default.- measure
String. Effect measure to add:
"PR","RR", or"OR". Overrides any measure implied bydesign.- design
String. Study design used to choose the effect measure when none is requested:
"cross_sectional"gives PR,"cohort"gives RR, and"case_control"gives OR.
Value
A simtab_result of class simtab_tb. Print it to see the
formatted table, convert it with as.data.frame(), or save it with
export_docx(), export_pptx(), or export_xlsx(). Unrounded results
are stored in $data.
Details
Statistical methods
Effect measures compare each row level with the reference level (ref),
taking the last column level as the event. Prevalence and risk ratios use
the Katz log interval (Katz et al., 1978) and odds ratios the Woolf logit
interval (Woolf, 1955). With strat, stratum-specific tables are pooled
with the Mantel-Haenszel estimator and tested with the Cochran-Mantel-Haenszel
test.
With test = TRUE, 2x2 tables use the N-1 chi-squared test (Campbell,
2007) and larger tables the Pearson chi-squared test, without continuity
correction. Fisher's exact test is chosen automatically only when an
expected count is below 1; request it with test = "fisher". Numeric
variables are compared with the t-test or ANOVA when summarised by the
mean, and with the Wilcoxon or Kruskal-Wallis test when summarised by the
median.
Numeric variables are treated as continuous unless they look like coded
categories: exactly two distinct whole numbers, or at most seven distinct
whole numbers with at least 20 observations. Use var.type to override.
Terse flags
Flags may be supplied as bare words in ... alongside the selected variables, or programmatically with flags =.
rowRow percentages.
colColumn percentages.
cell,percPercentages of the table total.
percreads better in one-variable tables.pr,rr,orAdd the corresponding crude effect measure.
pAdd a p-value from an automatically chosen test, like
test = TRUE.missShow missing values.
The old flags rp and m still work as aliases for pr and miss but are deprecated.
References
Campbell, I. (2007). Chi-squared and Fisher-Irwin tests of two-by-two tables with small sample recommendations. Statistics in Medicine, 26(19), 3661–3675. doi:10.1002/sim.2832 .
Katz, D., Baptista, J., Azen, S. P., & Pike, M. C. (1978). Obtaining confidence intervals for the risk ratio in cohort studies. Biometrics, 34(3), 469–474. doi:10.2307/2530610 .
Woolf, B. (1955). On estimating the relation between blood group and disease. Annals of Human Genetics, 19(4), 251–253. doi:10.1111/j.1469-1809.1955.tb01348.x .
Pearson, K. (1900). On the criterion that a given system of deviations from the probable in the case of a correlated system of variables is such that it can be reasonably supposed to have arisen from random sampling. Philosophical Magazine, Series 5, 50(302), 157–175. doi:10.1080/14786440009463897 .
Fisher, R. A. (1935). The Design of Experiments. Oliver & Boyd.
See also
table1() for many variables at once, regtab() for adjusted
effect measures, diag_test() for diagnostic accuracy, and
simtablr_references for all references cited by SimtablR.
Examples
# Frequencies of one variable
tb(epitabl, smoking)
#> Smoking status | Freq
#> ----------------+------
#> Never | 742
#> Former | 469
#> Current | 289
#> ----------------+------
#> Total | 1500
# Row percentages, a p-value, and crude prevalence ratios
tb(epitabl, smoking, adjudicated_acs, flags = c("row", "pr", "p"), ref = "Never")
#> | Adjudicated acute coronary syndrome
#> Smoking status | No Yes | Total
#> ----------------+--------------------------+-------
#> Never | 474 (63.9%) 268 (36.1%) | 742
#> Former | 302 (64.4%) 167 (35.6%) | 469
#> Current | 152 (52.6%) 137 (47.4%) | 289
#> ----------------+--------------------------+-------
#> Total | 928 572 | 1500
#>
#> Smoking status | PR (95% CI)
#> ----------------+-------------------------------
#> Never | 1.00 (Ref)
#> Former | 0.99 (0.84 - 1.15), p = 0.857
#> Current | 1.31 (1.12 - 1.53), p < 0.001
#> ----------------+-------------------------------
#> Total |
#>
#> Test: Pearson's Chi-squared test p-value = 0.001
# The same request with bare flags (shorthand)
tb(epitabl, smoking, adjudicated_acs, row, pr, p, ref = "Never")
#> | Adjudicated acute coronary syndrome
#> Smoking status | No Yes | Total
#> ----------------+--------------------------+-------
#> Never | 474 (63.9%) 268 (36.1%) | 742
#> Former | 302 (64.4%) 167 (35.6%) | 469
#> Current | 152 (52.6%) 137 (47.4%) | 289
#> ----------------+--------------------------+-------
#> Total | 928 572 | 1500
#>
#> Smoking status | PR (95% CI)
#> ----------------+-------------------------------
#> Never | 1.00 (Ref)
#> Former | 0.99 (0.84 - 1.15), p = 0.857
#> Current | 1.31 (1.12 - 1.53), p < 0.001
#> ----------------+-------------------------------
#> Total |
#>
#> Test: Pearson's Chi-squared test p-value = 0.001
# Odds ratio stratified by sex, with a Mantel-Haenszel pooled estimate
tb(epitabl, renal_impairment, adjudicated_acs, strat = sex, flags = "or", ref = "No")
#> | adjudicated_acs (Stratified)
#> Renal impairment (eGFR below 60 mL/min/1.73 m2) | Female : No Female : Yes
#> -------------------------------------------------+---------------------------
#> No | 362 188
#> Yes | 84 52
#> Total | 446 240
#> Mantel-Haenszel pooled: Yes |
#>
#> | adjudicated_acs (Stratified)
#> Renal impairment (eGFR below 60 mL/min/1.73 m2) | Male : No Male : Yes
#> -------------------------------------------------+-----------------------
#> No | 379 255
#> Yes | 103 77
#> Total | 482 332
#> Mantel-Haenszel pooled: Yes |
#>
#> | adjudicated_acs (Stratified)
#> Renal impairment (eGFR below 60 mL/min/1.73 m2) | Total
#> -------------------------------------------------+-------
#> No | 1184
#> Yes | 316
#> Total | 1500
#> Mantel-Haenszel pooled: Yes |
#>
#> | adjudicated_acs (Stratified)
#> Renal impairment (eGFR below 60 mL/min/1.73 m2) | OR MH (95% CI)
#> -------------------------------------------------+-------------------------------------------------
#> No |
#> Yes |
#> Total |
#> Mantel-Haenszel pooled: Yes | 1.14 (0.89 - 1.48), CMH p = 0.327, BD p = 0.788
#> ! Methodological warning
#> Outcome is common (22.1%); odds ratios can overstate the prevalence/risk
#> ratio. Consider measure = 'PR' for cross-sectional tables or
#> Poisson/log-binomial models for adjusted estimates.
#> Run simtablr_guidance("off") separately before printing to hide advice.
# A numeric variable summarised by group
tb(epitabl, age, adjudicated_acs, test = TRUE)
#> Variable 'age' automatically treated as continuous because it is numeric. Use 'var.type' to override.
#> | Adjudicated acute coronary syndrome
#> Age at index presentation (years) | No Yes
#> -----------------------------------------------+--------------------------
#> Age at index presentation (years) [Mean (SD)] | 60.5 (12.8) 64.4 (13.4)
#>
#> | Adjudicated acute coronary syndrome
#> Age at index presentation (years) | Total
#> -----------------------------------------------+-------------
#> Age at index presentation (years) [Mean (SD)] | 62.0 (13.2)
#>
#> Test: Welch Two Sample t-test p-value < 0.001