| Title: | User-Friendly Tables with Color Helpers for Data Exploration |
|---|---|
| Description: | Make it easy to deal with multiple cross-tables in data exploration, by creating them, manipulating them, and adding color helpers to highlight deviations (differences from totals, comparisons between lines or columns, contributions to variance, odds ratios, etc.) and significance (confidence intervals, stars, etc.). Create the same kind of tables for regression models, with a framework to compare model effects with their crude/observed counterpart systematically. All functions render data frames which can be easily manipulated. All tables can be exported with formats and colors to 'Excel', html and markdown. |
| Authors: | Brice Nocenti [aut, cre] |
| Maintainer: | Brice Nocenti <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 2.0.1 |
| Built: | 2026-10-17 10:54:18 UTC |
| Source: | https://github.com/bricenocenti/tabxplor |
5 226 people arrested for possession of a small quantity of marijuana. The outcome is whether the person was released with a summons rather than held. This is the running example of the All else equal article: 86 % of white arrestees were released against 74 % of black arrestees, and the article asks what survives of that gap when people alike on everything else are compared.
car_arrestscar_arrests
A tibble of 5 226 rows and 8 columns.
Released with a summons? "Yes" first – it is what the article studies.
The arrestee's race as the police recorded it: "White" first, then "Black".
1997 to 2002.
Age in years.
Female or Male.
Employed? "Yes" first.
A Canadian citizen? "Yes" first.
On how many of six police databases the person's name already appeared, 0 to 6.
The complete Arrests data of the carData package (John Fox, Sanford Weisberg and
Brad Price), GPL (>= 2) – with thanks; gathered by Michael Friendly for a series in the
Toronto Star. tabxplor's copy changes only the level order: the yes/no items read "Yes"
first, and colour starts at "White".
tab(car_arrests, colour, released, pct = "row", color = "difference")tab(car_arrests, colour, released, pct = "row", color = "difference")
Nine months' salary for 397 professors at one US college, collected by the institution to monitor a pay gap. Used in the Reading a regression article to show a gap that grows under adjustment, and then a mediator: rank explains the gap away, but rank is itself part of what is unequal.
car_salariescar_salaries
A tibble of 397 rows and 7 columns.
AsstProf, AssocProf, then Prof.
"A" (theoretical) or "B" (applied).
Years since the PhD.
Years of service.
Female or Male.
Nine-month salary, in US dollars.
Full professor or not: the same information as rank, asked as the yes/no
question a percentage can answer. Added by tabxplor.
The complete Salaries data of the carData package (John Fox, Sanford Weisberg and
Brad Price), GPL (>= 2) – with thanks. tabxplor's copy adds is_prof and orders rank from
assistant to full professor.
tab_reg(car_salaries, "salary", c("sex", "discipline"))tab_reg(car_salaries, "salary", c("sex", "discipline"))
Turn one or several confidence levels into the two-sided normal (z) thresholds they
correspond to, rounded for readability. It is a convenience for writing the zscore color
break scale (set_color_breaks) in the vocabulary you already use elsewhere —
confidence levels — instead of remembering that 95 % is 1.96. The scale itself always stores plain
z magnitudes, so conf_level_to_z(0.95) and 1.96 are strictly interchangeable.
conf_level_to_z(conf_level, digits = 2)conf_level_to_z(conf_level, digits = 2)
conf_level |
A numeric vector of confidence levels, each between 0 and 1
(e.g. |
digits |
Number of digits to round to (default 2). Rounding keeps color legends readable
( |
A numeric vector of positive z thresholds, the same length as conf_level.
conf_level_to_z(c(0.95, 0.99)) # the default `zscore` break scale (color = "contrib", color_signif = "guaranteed_effect") conf_level_to_z(c(0.95, 0.99, 0.9999, 1 - 2e-9)) set_color_breaks(zscore = conf_level_to_z(c(0.95, 0.999))) set_color_breaks(zscore = c(2, 3, 4, 6)) # or plain z values, identicallyconf_level_to_z(c(0.95, 0.99)) # the default `zscore` break scale (color = "contrib", color_signif = "guaranteed_effect") conf_level_to_z(c(0.95, 0.99, 0.9999, 1 - 2e-9)) set_color_breaks(zscore = conf_level_to_z(c(0.95, 0.999))) set_color_breaks(zscore = c(2, 3, 4, 6)) # or plain z values, identically
A survey of 300 tea drinkers, used here for its three batteries of yes/no items – the shape a
multiple-answer question ("which of these apply to you?") arrives in. Six items say when people
drink tea, six say where, and fourteen say what they think it does for them. See
vignette("tabxplor") for what a battery does in a table, and score_from_lv1() for turning one
into a single summed score.
facto_teafacto_tea
A tibble of 300 rows and 36 columns. The ones the vignettes use:
When do you drink tea?
Where do you drink tea?
Do you play a sport?
Socio-professional category, 7 levels.
F or M.
The other columns describe the tea itself (Tea, How, sugar, how, where, price,
frequency), the drinker (age, age_Q), and what they associate tea with (healthy,
relaxing, exciting, slimming, and ten more). Every two-level item reads "yes" first.
The complete tea data of the FactoMineR package (Francois Husson, Julie Josse,
Sebastien Le and Jeremy Mazet), GPL (>= 2) – with thanks. tabxplor's copy changes only the
level order: in each yes/no item the "yes" answer comes first, and its label loses the
separator dot the original spells it with ("Not.tea time" becomes "Not tea time").
tab(facto_tea, SPC, c(breakfast, evening), pct = "row", levels = "first", na = "drop")tab(facto_tea, SPC, c(breakfast, evening), pct = "row", levels = "first", na = "drop")
Recoding a factor with forcats::fct_recode() means typing every level name exactly, and a typo
is silently ignored. fct_recode_helper() writes that code for you: it prints a ready-to-paste
mutate() call with one fct_recode() per variable, each level already written as
"level" = "level". You then only edit the new names on the left, and delete the lines you keep.
With a few variables, each level carries its frequency and count as a comment, which is what tells
you which small levels to merge. A column with a label attribute (data imported by haven)
gets that label as a comment title.
fct_recode_helper( data, .cols = -where(is.numeric), name_in, name_out, freq = NULL, style = c("mutate", "base"), reminder = TRUE, cat = TRUE )fct_recode_helper( data, .cols = -where(is.numeric), name_in, name_out, freq = NULL, style = c("mutate", "base"), reminder = TRUE, cat = TRUE )
data |
The data frame. |
.cols |
<tidy-select> The variables to recode. Default: every non-numeric column. |
name_in |
The input data frame's name (default: the expression given as |
name_out |
The output data frame's name, if different from |
freq |
Print each level's frequency and count as a comment; defaults to |
style |
|
reminder |
Print a |
cat |
Print to console, or open a temporary file when there are more than 5 variables;
|
With cat = TRUE (default), the text printed to console (or written to a temp R file for
more than 5 variables), returned invisibly. With cat = FALSE, a tibble of the recode text.
fct_recode_helper(forcats::gss_cat, c(marital, race))fct_recode_helper(forcats::gss_cat, c(marital, race))
fmt vector, the tabxplor cellfmt vectors, of class tabxplor_fmt, powers tabxplor
and tab tibbles.
As a record, they stores all data necessary to
calculate percentages, Chi2 metadata or confidence intervals, but also to format and
color the table to help the user read it. You can access this data with
vctrs::field, or change it with
vctrs:field<-. Its per-cell fields are listed below.
The other arguments are attributes, attached not to each value but to
the whole vector, like scale, col_var, totcol or color. You can get
them with attr and modify them with
attr<-. Special functions listed below are made to
facilitate programming with with tabxplor formatted numbers.
taxplfmt vectors can use all standard operations, like +, -, sum(), or c(),
using vctrs.
fmt( n = integer(), scale = "level_n", digits = rep(0L, length(n)), display = est_default_display(scale[1]), wn = rep(NA_real_, length(n)), pct = rep(NA_real_, length(n)), mean = rep(NA_real_, length(n)), diff = rep(NA_real_, length(n)), ratio = rep(NA_real_, length(n)), ctr = rep(NA_real_, length(n)), var = rep(NA_real_, length(n)), ci = rep(NA_real_, length(n)), ci_inf = rep(NA_real_, length(n)), ci_sup = rep(NA_real_, length(n)), pvalue = rep(NA_real_, length(n)), or = rep(NA_real_, length(n)), tot_n = rep(NA_real_, length(n)), n_eff = rep(NA_real_, length(n)), obs = rep(NA_real_, length(n)), gap_se = rep(NA_real_, length(n)), row_kind = rep("data", length(n)), in_tottab = rep(FALSE, length(n)), in_refrow = rep(FALSE, length(n)), in_totrow = NULL, comp_all = NA, ref = "", pct_type = "none", col_var = "", col_group = "", totcol = FALSE, refcol = FALSE, color = "", color_signif = "ignore", model_family = "", role = "", conf_level = NA_real_, degf = NA_real_, basis = "n", ci_method = "", ... ) is_fmt(x)fmt( n = integer(), scale = "level_n", digits = rep(0L, length(n)), display = est_default_display(scale[1]), wn = rep(NA_real_, length(n)), pct = rep(NA_real_, length(n)), mean = rep(NA_real_, length(n)), diff = rep(NA_real_, length(n)), ratio = rep(NA_real_, length(n)), ctr = rep(NA_real_, length(n)), var = rep(NA_real_, length(n)), ci = rep(NA_real_, length(n)), ci_inf = rep(NA_real_, length(n)), ci_sup = rep(NA_real_, length(n)), pvalue = rep(NA_real_, length(n)), or = rep(NA_real_, length(n)), tot_n = rep(NA_real_, length(n)), n_eff = rep(NA_real_, length(n)), obs = rep(NA_real_, length(n)), gap_se = rep(NA_real_, length(n)), row_kind = rep("data", length(n)), in_tottab = rep(FALSE, length(n)), in_refrow = rep(FALSE, length(n)), in_totrow = NULL, comp_all = NA, ref = "", pct_type = "none", col_var = "", col_group = "", totcol = FALSE, refcol = FALSE, color = "", color_signif = "ignore", model_family = "", role = "", conf_level = NA_real_, degf = NA_real_, basis = "n", ci_method = "", ... ) is_fmt(x)
n |
The underlying count, as an integer vector of length |
scale |
What the column estimates, as a single string (an attribute, not a field): one key into the declared library of estimate scales. It says which field holds the estimate, what its null value is, whether the scale is additive or multiplicative, and which colour ladder it reads.
|
digits |
The number of digits, as an integer, or an integer vector the length
of |
display |
The display type : the name of the field you want to show when printing
the vector, as a single string or a character vector the length of |
wn |
The underlying weighted counts, as a double vector the length of
|
pct |
The percentages, as a double vector the length of |
mean |
The means, as a double vector the length of |
diff |
The differences (from totals or first cells),
as a double vector the length of |
ratio |
The ratio to the reference (relative risk for percentages, mean ratio for
means), as a double vector the length of |
ctr |
The contributions of cells to (sub)tables variances,
as a double vector the length of |
var |
The cells variances, as a double vector the length of |
ci |
The confidence interval half-width (margin of error), as a double vector the
length of |
ci_inf, ci_sup
|
The lower and upper bounds of the confidence interval, as double
vectors the length of |
pvalue |
The per-cell significance p-value, as a double vector the length of
|
or |
The odds ratio (for a 3+ level variable, the OR of each level versus the reference),
as a double vector the length of |
tot_n |
The cell's own (unweighted) percentage base, as a double vector the length
of |
n_eff |
The effective sample size used for this cell's confidence interval,
|
obs |
The value this cell's estimate is COMPARED TO by the |
gap_se |
The standard error of the GAP between this cell's estimate and |
row_kind |
What kind of row the cell sits in — one of |
in_tottab |
|
in_refrow |
|
in_totrow |
|
comp_all |
|
ref |
The type of difference of the vector. Cf. |
pct_type |
For a percentage column, what the percentage is a percentage OF, and hence which
axis its reference lies on (as a single string): |
col_var |
The name of the |
col_group |
The sub-population this column's block belongs to: a level of a
|
totcol |
|
refcol |
|
color |
The colour measure, as a single string — how a cell's value is compared to colour
it (significance is handled separately by
The value is validated and normalised: every accepted spelling — the discipline's
acronyms included ( |
color_signif |
How significance gates the color, as a single string
( |
model_family |
For regression tables ( |
role |
For regression tables ( |
conf_level |
The confidence level this column's interval and thresholds were computed at, as
a single number in (0, 1). |
degf |
The degrees of freedom this column's interval is referred to. On a cross-table that is
the survey design's |
basis |
How this column's interval and significance were computed — |
ci_method |
Which interval ENGINE built this column's bounds — |
... |
In |
x |
The object to test, to get a field in, or to modify. |
A vector of class tabxplor_fmt.
A logical vector.
is_fmt(): a test function for class fmt.
A fmt cell carries 21 fields. Many are NA when the quantity was not requested; read one with x$field or
vctrs::field(), and see them all with
vctrs::vec_data():
n — the unweighted count.
display — which field this cell shows (a bare name, or a {} template).
digits — how many decimals this cell prints.
wn — the weighted count.
pct — the percentage.
mean — the mean, on a numeric column variable.
diff — the difference from the reference cell (percentage points, or the outcome's own units).
ratio — the ratio to the reference cell (a relative risk, or a ratio of means).
ctr — the cell's contribution to the table's Chi-2.
var — the column's variance quantity – which one is given by its scale.
ci_inf — the lower bound of the confidence interval.
ci_sup — the upper bound of the confidence interval.
pvalue — the cell's own significance p-value, which the stars read.
or — the odds ratio against the ref2 level.
tot_n — the cell's own base — the count its percentage is computed on.
n_eff — the effective sample size its interval was computed on (weights or a survey design).
obs — tab_reg() only: the observed (crude) effect the modelled one is compared to.
gap_se — tab_reg() only: the standard error of the gap between the estimate and obs.
row_kind — what kind of row the cell sits in — see get_row_kind().
in_tottab — is the cell in a total table (logical).
in_refrow — is the cell in a reference row (logical).
Generated from the package's own display table, so it cannot drift from what
get_num() reads. Each of
pct, n, wn, mean, diff, ratio, or, ctr, var, obs, pvalue shows the field of the same
name, described above. The rest are composed or derived by the pipeline itself, and
the last few are not meant to be typed:
est — the estimate, whatever this column estimates — an odds ratio, a risk difference, a coefficient, a percentage. The one token that means the same thing on every table.
base — the level the estimate sits on: the percentage, the mean or the count. On a plain percentage table it is the same number as est; beside a regression effect it is the adjusted prediction.
ci — the confidence interval of whatever the column compares, as [low;high].
moe — the margin of error — the same interval as ci, written as the half-width +/-x around the estimate. Void where the column compares a RATIO: a ratio's interval is symmetric on the LOG scale, so it has no half-width.
odds — the odds — pct / (1 - pct), the quantity an odds ratio is a ratio of. Printed on the odds ratio's own ladder, so a cell below 1 reads its inverse ("1/2.60") unless options(tabxplor.ratio_print = "raw") asks for the plain number. Void where the percentage is 1 and the odds infinite.
sd — the standard deviation, in the variable's own unit.
cv — the coefficient of variation — the standard deviation as a percentage of the mean.
resid — the adjusted standardized residual – whether the cell departs from independence. Derived from the p-value and the sign of ctr, so it is read-only.
coef — the estimate on the model's LINK scale — the coefficient a linear or log-link model fitted. The same number as est where the column is already additive, its logarithm where the column shows a ratio.
gap — how far adjustment moved the effect: the gap between the modelled estimate and its observed counterpart, on the estimate's own scale. What color = "adjustment" grades — readable in print and Excel, not only in an html tooltip.
gof — a model-fit statistic (N, R2, AIC, BIC, dispersion).
gof_warn — a model-fit statistic past the threshold its check is read against.
n_range — the unweighted base: one count, or a min-max range over the table.
blank — nothing: a cell masked by n_min.
rr — the legacy synonym of ratio, still accepted.
OR — the acronym spelling of or, still accepted.
tabxplor-display for the {} grammar and the named layouts display
accepts; fmt_fields and fmt_attributes for the accessors.
library(dplyr) f <- fmt(n = c(7, 19, 2), pct = c(0.25, 0.679, 0.07), scale = "level_pct", pct_type = "row") f # To get the currently displayed field : get_num(f) # To modify the currently displayed field : set_num(f, c(1, 0, 0)) # See all the underlying fields of a fmt vector (a data frame with a number of rows # equal to the length of the vector) : vctrs::vec_data(f) # To get the numbers of digits : vctrs::field(f, "digits") f$digits # To get the count : vctrs::field(f, "n") f$n # To get the display : vctrs::field(f, "display") f$display # To modify a field, you can use `dplyr::mutate` on the fmt vector, # referring to the names of the columns of the underlying data.frame (`vctrs::vec_data`) : vctrs::`field<-`(f, "pct", c(1, 0, 0)) mutate(f, pct = c(1, 0, 0)) # See all the attributes of a fmt vector : attributes(f) # To modify the "pct_type" attribute of a fmt vector (what the percentage is a percentage OF) : set_pct_type(f, "col") # To modify the "color" attribute of a fmt vector : set_color(f, "contrib") tabs <- tab(starwars, sex, hair_color, gender, na = "drop", pct = "row", other_if_less_than = 5) # To identify the total columns, and work with them : is_totcol(tabs) tabs |> mutate(across(where(is_totcol), ~ "total column")) # To identify the total rows, and work with them : is_totrow(tabs) tabs |> mutate(across( where(is_fmt), ~ if_else(is_totrow(.), true = "into_total_row", false = "normal_cell") )) # To identify the total tables, and work with them : tottabs <- is_tottab(tabs) tabs |> tibble::add_column(tottabs) |> mutate(total = if_else(tottabs, "part of a total table", "normal cell")) # To access the displayed numbers, as numeric vectors : tabs |> mutate(across(where(is_fmt), get_num)) # To access the displayed numbers, as character vectors (without colors) : tabs |> mutate(across(where(is_fmt), format)) # To access the (non-displayed) differences of the cells percentages from totals : tabs |> mutate(across(where(is_fmt), ~ vctrs::field(., "diff"))) # To do more complex operations, like creating a new column with standard deviation and # print it with 2 decimals, use `dplyr::mutate` on all the fmt columns of a table : tab(forcats::gss_cat, race, c(age, tvhours), marital, digits = 1L, comp = "all", color = "auto") |> dplyr::mutate(dplyr::across( #Mutate over the whole table. c(age, tvhours), ~ dplyr::mutate(., #Mutate over each fmt vector's underlying data.frame. var = sqrt(var), display = "var", digits = 2L) |> set_color("no"), .names = "{.col}_sd" ))library(dplyr) f <- fmt(n = c(7, 19, 2), pct = c(0.25, 0.679, 0.07), scale = "level_pct", pct_type = "row") f # To get the currently displayed field : get_num(f) # To modify the currently displayed field : set_num(f, c(1, 0, 0)) # See all the underlying fields of a fmt vector (a data frame with a number of rows # equal to the length of the vector) : vctrs::vec_data(f) # To get the numbers of digits : vctrs::field(f, "digits") f$digits # To get the count : vctrs::field(f, "n") f$n # To get the display : vctrs::field(f, "display") f$display # To modify a field, you can use `dplyr::mutate` on the fmt vector, # referring to the names of the columns of the underlying data.frame (`vctrs::vec_data`) : vctrs::`field<-`(f, "pct", c(1, 0, 0)) mutate(f, pct = c(1, 0, 0)) # See all the attributes of a fmt vector : attributes(f) # To modify the "pct_type" attribute of a fmt vector (what the percentage is a percentage OF) : set_pct_type(f, "col") # To modify the "color" attribute of a fmt vector : set_color(f, "contrib") tabs <- tab(starwars, sex, hair_color, gender, na = "drop", pct = "row", other_if_less_than = 5) # To identify the total columns, and work with them : is_totcol(tabs) tabs |> mutate(across(where(is_totcol), ~ "total column")) # To identify the total rows, and work with them : is_totrow(tabs) tabs |> mutate(across( where(is_fmt), ~ if_else(is_totrow(.), true = "into_total_row", false = "normal_cell") )) # To identify the total tables, and work with them : tottabs <- is_tottab(tabs) tabs |> tibble::add_column(tottabs) |> mutate(total = if_else(tottabs, "part of a total table", "normal cell")) # To access the displayed numbers, as numeric vectors : tabs |> mutate(across(where(is_fmt), get_num)) # To access the displayed numbers, as character vectors (without colors) : tabs |> mutate(across(where(is_fmt), format)) # To access the (non-displayed) differences of the cells percentages from totals : tabs |> mutate(across(where(is_fmt), ~ vctrs::field(., "diff"))) # To do more complex operations, like creating a new column with standard deviation and # print it with 2 decimals, use `dplyr::mutate` on all the fmt columns of a table : tab(forcats::gss_cat, race, c(age, tvhours), marital, digits = 1L, comp = "all", color = "auto") |> dplyr::mutate(dplyr::across( #Mutate over the whole table. c(age, tvhours), ~ dplyr::mutate(., #Mutate over each fmt vector's underlying data.frame. var = sqrt(var), display = "var", digits = 2L) |> set_color("no"), .names = "{.col}_sd" ))
fmt column attribute, by nameThe generic form of the get_*() / set_*() family: one function covering every per-column
attribute a tabxplor_fmt vector carries, so a helper can loop over them instead of naming each.
The named accessors (get_scale(), get_col_var(), is_totcol(), …) remain the readable way to
address one known attribute.
fmt_attr(x, name) fmt_attr(x, name) <- valuefmt_attr(x, name) fmt_attr(x, name) <- value
x |
A |
name |
The attribute: one of |
value |
The new value. Written through the attribute's own setter, so it is validated
exactly as |
The stored value (its declared default when the attribute is unset). On a data.frame, one
entry per fmt column, named. Writing returns the modified vector.
tab_columns() for every column's attributes at once; fmt() for what each one means.
x <- fmt(n = c(10, 20), pct = c(0.3, 0.7), scale = "level_pct", pct_type = "row") fmt_attr(x, "scale") fmt_attr(x, "col_var") <- "region" fmt_attr(x, "col_var")x <- fmt(n = c(10, 20), pct = c(0.3, 0.7), scale = "level_pct", pct_type = "row") fmt_attr(x, "scale") fmt_attr(x, "col_var") <- "region" fmt_attr(x, "col_var")
fmt vectorRead and write the facts that hold for a whole column: what it estimates, which percentage base
it rests on, which reference it is compared to, how it is coloured, and how its confidence
interval was built. They are stored on the vector, not on the table, so a column keeps them when
it is extracted, renamed or piped through dplyr.
fmt_attr() reaches any of them by name — these are the readable way to address one you know.
tab_columns() shows them all, for every column of a table at once.
get_scale(x, ...) set_scale(x, scale) get_pct_type(x, ...) set_pct_type(x, pct_type) is_totcol(x, ...) as_totcol(x, totcol = TRUE) get_comp_all(x, replace_na = TRUE) set_comp_all(x, comp_all = FALSE) get_ref_type(x, ...) set_ref_type(x, ref) set_diff_type(x, ref) get_col_var(x, ...) set_col_var(x, col_var) get_col_group(x, ...) get_model_family(x, ...) set_model_family(x, model_family) get_ci_method(x, ...) is_refcol(x, ...) as_refcol(x, refcol = TRUE) get_color(x, ...) get_color_bg(x, ...) get_color_signif(x, ...) set_color(x, color) set_color_signif(x, color_signif)get_scale(x, ...) set_scale(x, scale) get_pct_type(x, ...) set_pct_type(x, pct_type) is_totcol(x, ...) as_totcol(x, totcol = TRUE) get_comp_all(x, replace_na = TRUE) set_comp_all(x, comp_all = FALSE) get_ref_type(x, ...) set_ref_type(x, ref) set_diff_type(x, ref) get_col_var(x, ...) set_col_var(x, col_var) get_col_group(x, ...) get_model_family(x, ...) set_model_family(x, model_family) get_ci_method(x, ...) is_refcol(x, ...) as_refcol(x, refcol = TRUE) get_color(x, ...) get_color_bg(x, ...) get_color_signif(x, ...) set_color(x, color) set_color_signif(x, color_signif)
x |
The object to test, to get a field in, or to modify. |
... |
In |
scale |
What the column estimates, as a single string (an attribute, not a field): one key into the declared library of estimate scales. It says which field holds the estimate, what its null value is, whether the scale is additive or multiplicative, and which colour ladder it reads.
|
pct_type |
For a percentage column, what the percentage is a percentage OF, and hence which
axis its reference lies on (as a single string): |
totcol |
|
replace_na |
By default, |
comp_all |
|
ref |
The type of difference of the vector. Cf. |
col_var |
The name of the |
model_family |
For regression tables ( |
refcol |
|
color |
The colour measure, as a single string — how a cell's value is compared to colour
it (significance is handled separately by
The value is validated and normalised: every accepted spelling — the discipline's
acronyms included ( |
color_signif |
How significance gates the color, as a single string
( |
A getter returns the stored value — its declared default where the attribute was never
set ("" for a name, FALSE for a flag, NA where there is none) — and answers once per
fmt column when given a data.frame. A setter returns the modified fmt vector.
get_scale(): get the estimate scale of fmt columns (at fmt level or tab level)
set_scale(): set the estimate scale attribute of a fmt vector
get_pct_type(): get which kind of percentage fmt columns hold (at fmt level or tab level)
set_pct_type(): set the percentage-type attribute of a fmt vector
is_totcol(): test function for total columns
(at fmt level or tab level)
as_totcol(): set the "totcol" attribute of a fmt vector
get_comp_all(): get comparison level of fmt columns
set_comp_all(): set the comparison level attribute of a fmt vector
get_ref_type(): get differences type of fmt columns (at fmt level or tab level)
set_ref_type(): set the reference attribute of a fmt vector — which row or column a
comparison is made against. It is the writer of the attribute get_ref_type() reads.
set_diff_type(): Use
set_ref_type(), which shares its stem
with the getter get_ref_type() and with the ref attribute both of them address.
get_col_var(): get names of column variable of fmt columns (at fmt level or tab level)
set_col_var(): set the "col_var" attribute of a fmt vector
get_col_group(): get the sub-population of fmt columns (at fmt level or tab level)
get_model_family(): get the regression model family of fmt columns (at fmt or tab level)
set_model_family(): set the "model_family" attribute of a fmt vector (the per-column
regression family, "" on crosstabs)
get_ci_method(): get the interval method of fmt columns (at fmt level or tab level)
is_refcol(): test function for reference columns (at fmt level or tab level)
as_refcol(): set the "ref_col" attribute of a fmt vector
get_color(): get color (at fmt level or tab level)
get_color_bg(): get the background-channel color measure (NA when there is none)
get_color_signif(): get the significance policy ("ignore" / "grey_non_signif" / "guaranteed_effect")
set_color(): set the "color" attribute of a fmt vector
set_color_signif(): set the significance policy attribute of a fmt vector
fmt_attr() to address an attribute by name; tab_columns() for a whole table;
fmt() for what every attribute means; fmt_fields for the per-cell values.
fmt vectorRead and write the values that vary from cell to cell: the displayed number, its decimals, its
p-value, and the kind of row each cell sits in. Every fmt vector carries all of them, an
inapplicable one stored as NA — so these always answer, even on a column where the field
means nothing.
Use them on a single fmt vector or, through dplyr::across(where(is_fmt), ...), on a whole
table. To reach a field these do not name, use x$<field> or vctrs::field().
get_num(x) set_num(x, value) is_totrow(x, ...) get_row_kind(x) set_row_kind(x, row_kind) as_totrow(x, in_totrow = TRUE) is_tottab(x, ...) as_tottab(x, in_tottab = TRUE) set_display(x, value) is_refrow(x, ...) as_refrow(x, in_refrow = TRUE) get_digits(x) get_pvalue(x) set_digits(x, value) set_pvalue(x, value)get_num(x) set_num(x, value) is_totrow(x, ...) get_row_kind(x) set_row_kind(x, row_kind) as_totrow(x, in_totrow = TRUE) is_tottab(x, ...) as_tottab(x, in_tottab = TRUE) set_display(x, value) is_refrow(x, ...) as_refrow(x, in_refrow = TRUE) get_digits(x) get_pvalue(x) set_digits(x, value) set_pvalue(x, value)
x |
The object to test, to get a field in, or to modify. |
value |
The value you want to inject in some |
... |
In |
row_kind |
The kind of row a cell sits in (see |
in_totrow |
|
in_tottab |
|
in_refrow |
|
A getter returns a vector the length of x; a setter the modified fmt vector. Given a
data.frame, a getter answers once per fmt column.
get_num(): get the currently displayed field
set_num(): set the currently displayed field (not changing display type)
is_totrow(): test function to detect cells in total rows
(at fmt level or tab level)
get_row_kind(): get the "row_kind" field: what kind of row each cell sits in
(see the Row kinds section).
set_row_kind(): set the "row_kind" field
as_totrow(): set the "total" row kind (belong to total row)
is_tottab(): test function to detect cells in total tables
(at fmt level or tab level)
as_tottab(): set the "in_tottab" field (belong to total table)
set_display(): set the "display" vctrs::field of a fmt vector, or of
all of them in the whole tibble.
is_refrow(): test function to detect cells in reference rows
(at fmt level or tab level)
as_refrow(): set the "in_refrow" field (belong to reference row)
get_digits(): get the "digits" field
get_pvalue(): get the per-cell p-value (what the significance stars read)
set_digits(): set the "digits" field
set_pvalue(): set the per-cell p-value. set_pvalue(x, NA_real_) is how a duplicated,
purely descriptive copy of a column loses its stars: the stored p-value is their only source.
The row_kind field says what kind of row a cell sits in.
"data"a real body row.
"total"a total row (the only kind is_totrow() asks about).
"n"the base-count row.
"pct"the add_pct percentage row.
"pvalue"an appended test row: a crosstab's chi2 or F, a regression's per-term test.
"gof"a regression goodness-of-fit / model-summary footer row.
"blank"a spacer row between footer blocks.
fmt() for what every field means and how to build a cell; fmt_attributes for the
per-column facts; vignette("tabxplor-programming").
fmt vectorThe html color code of a fmt vector
fmt_get_color_code(x, type = "text", theme = "light", ...)fmt_get_color_code(x, type = "text", theme = "light", ...)
x |
The fmt vector to get the html color codes from. |
type |
The style type, |
theme |
Is your console or html table background |
... |
Absorbs deprecated arguments (e.g. |
A character vector with html color codes, of the length of the initial vector.
tabs <- tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") dplyr::mutate(tabs, across(where(is_fmt), fmt_get_color_code))tabs <- tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") dplyr::mutate(tabs, across(where(is_fmt), fmt_get_color_code))
Draws every estimate of a table with its confidence interval, its significance and its colour –
for a cross-table from tab as much as for a regression table from
tab_reg. It reads the table and never re-fits anything: every number and every
colour comes from the cell it was printed from, so the figure and the table cannot disagree.
(Its sibling reg_check_plots is the opposite: model checks always re-fit, because
they are about residuals, which no table carries.)
forest_plot( x, columns = NULL, what = c("auto", "effect", "level"), observed = c("auto", "band", "point", "ci", "none"), center = c("n", "estimate", "none"), display = NULL, layout = c("keep", "auto", "transpose"), facet = NULL, color = TRUE, guide = c("gridlines", "bands", "none"), intercept = FALSE, totals = FALSE, offset = 0.25, label_offset = 0.3, max_size = 6, footer = c("short", "full", "none"), footer_width = 130L, legend = "auto", theme = NULL, lang = NULL, caption = NULL, subtext = TRUE, return_data = FALSE, ... )forest_plot( x, columns = NULL, what = c("auto", "effect", "level"), observed = c("auto", "band", "point", "ci", "none"), center = c("n", "estimate", "none"), display = NULL, layout = c("keep", "auto", "transpose"), facet = NULL, color = TRUE, guide = c("gridlines", "bands", "none"), intercept = FALSE, totals = FALSE, offset = 0.25, label_offset = 0.3, max_size = 6, footer = c("short", "full", "none"), footer_width = 130L, legend = "auto", theme = NULL, lang = NULL, caption = NULL, subtext = TRUE, return_data = FALSE, ... )
x |
A table made with |
columns |
Value columns to draw, by name. |
what |
|
observed |
For a regression table with |
center |
What marks the estimate: |
display |
What that value prints – a |
layout |
Which axis is read and which is faceted: |
facet |
|
color |
Set to |
guide |
|
intercept |
Draw the regression |
totals |
Draw total rows and total columns. |
offset |
How far below the estimate the observed value sits, as a fraction of a row; raise it for a tall figure with few rows. Under an adjustment colour the arrow takes this row and the observed value drops one further. |
label_offset |
How far above the estimate its value is printed, as a fraction of a row. |
max_size |
Area of the largest marker, when |
footer |
|
footer_width |
Characters per footer line, since a ggplot caption does not wrap on its own. Use a larger number for a wide figure, smaller for a narrow one. |
legend |
Where the colour legend goes: |
theme |
|
lang |
Colour-legend language: |
caption |
A caption. |
subtext |
Include the table's subtext and footer lines in the caption. |
return_data |
Return the long estimate tibble instead of the plot. |
... |
Retired arguments, accepted and ignored with a deprecation message since 2.0.0.
Anything else is an error naming the argument you meant, as it already was in |
What is drawn. Always a deviation: the effect a regression estimates, or, for a
cross-table, the comparison its color = grades. The level it sits on (the
percentage, the mean, the adjusted probability) is printed above each whisker instead, so position
and number say two different things; what = "level" swaps them.
The gridlines are the table's colour ladder (set_color_breaks), labelled with the
same glyphs as the footer and continued as far as the data goes. The whisker takes the colour of
its cell whole, so significance is read off it and there are no stars.
A table that mixes units (an odds ratio beside a mean difference) gets one axis per panel, each in its own transform, with panels measuring the same thing sharing one comparable range.
The observed comparison. With empirical = TRUE, a regression estimate carries its crude
counterpart. observed = "band" (the default when testable) draws a bracket at plus-or-minus
the margin of error of the difference: the modelled point falls outside it exactly when the gap
test rejects. Two correlated intervals should not be compared by overlap, which is why the crude
one is not drawn by default; observed = "ci" restores it.
A ggplot (or a list of them), ready for + theme() and ggsave().
reg_check_plots for the model checks, tab_export to export
the table itself.
if (requireNamespace("ggplot2", quietly = TRUE)) { t <- tab(forcats::gss_cat, race, marital, pct = "row", ci = "ref", color = TRUE) forest_plot(t) forest_plot(t, guide = "bands") # the teaching mode }if (requireNamespace("ggplot2", quietly = TRUE)) { t <- tab(forcats::gss_cat, race, marital, pct = "row", ci = "ref", color = TRUE) forest_plot(t) forest_plot(t, guide = "bands") # the teaching mode }
The tests a table carries and prints under itself: a crosstab's chi-squared or ANOVA, a
regression's model-fit statistics and global tests. get_test() hands them back as a tidy
tibble — one row per test, keyed by var (the row variable, the predictor, or ""
for the whole table) and col (the column variable it keys under) — so a test can be
filtered, reshaped or reported like any other data. A new kind of test is new rows, never new
columns.
The remaining columns name the statistic (test, statistic, df1, df2,
pvalue), the base it was computed on (n, min_e, deff) and its effect
size (effect_size, es_type). Per-CELL contributions to the chi-squared are not here:
they are the ctr field of the cells themselves (tabs$Total$ctr).
get_test(x)get_test(x)
x |
A |
A tibble of tests — empty, with the same columns, when the table ran none (build them
with tab(test = TRUE)); NULL only when x has lost its attributes.
tab() for test =, tab_structure() and tab_columns() for the rest of a table's
metadata.
tabs <- tab(forcats::gss_cat, race, marital, test = TRUE) get_test(tabs)tabs <- tab(forcats::gss_cat, race, marital, test = TRUE) get_test(tabs)
forcats::gss_cat with levels merged into readable groups, and each variable's first level
chosen as the reference the colors and the models compare everything else to. The data set most
examples and vignettes are built on.
gss_cat_data_formatting()gss_cat_data_formatting()
A tibble of 21483 rows: the US General Social Survey, 2000-2014.
TRUE for a table built by tab, tab_reg or any of their
variants — i.e. for a tabxplor_tab (a tabxplor_grouped_tab with tab_vars).
tab_structure answers the fuller question: what structure is it, and what can be done
with it.
is_tab(x)is_tab(x)
x |
An object to test. |
A single logical.
tab_structure(), tab_get_vars().
Crosstables
jmvtab( data, row_vars = NULL, col_vars = NULL, tab_vars = NULL, wt = NULL, pct = "no", color = "no", color_signif = "ignore", test = FALSE, anova = "welch", na = "keep", lvs = "all", cleannames = TRUE, ref_levels = NULL, levels_order = NULL, levels_collapse = NULL, shape = NULL, ref = "auto", ref2 = "first", comp = "tab", ci = "auto", conf_level = 0.95, stars = FALSE, design_effect = FALSE, ci_method_cell = "wilson", ci_method_diff = "newcombe", ci_method_mean_diff = "welch", ci_method_mean_ratio = "robust", tab_theme = "light", totaltab = "line", wrap_rows = 35, wrap_cols = 15, display = "auto", n = "range", add_pct = FALSE, subtext = "", digits = "0", n_min = 0, export_format = "excel", exportExcel = FALSE, export_dir = "~/Documents", export_filename = "Table", resetPath = FALSE, xl_replace = FALSE )jmvtab( data, row_vars = NULL, col_vars = NULL, tab_vars = NULL, wt = NULL, pct = "no", color = "no", color_signif = "ignore", test = FALSE, anova = "welch", na = "keep", lvs = "all", cleannames = TRUE, ref_levels = NULL, levels_order = NULL, levels_collapse = NULL, shape = NULL, ref = "auto", ref2 = "first", comp = "tab", ci = "auto", conf_level = 0.95, stars = FALSE, design_effect = FALSE, ci_method_cell = "wilson", ci_method_diff = "newcombe", ci_method_mean_diff = "welch", ci_method_mean_ratio = "robust", tab_theme = "light", totaltab = "line", wrap_rows = 35, wrap_cols = 15, display = "auto", n = "range", add_pct = FALSE, subtext = "", digits = "0", n_min = 0, export_format = "excel", exportExcel = FALSE, export_dir = "~/Documents", export_filename = "Table", resetPath = FALSE, xl_replace = FALSE )
data |
A data.frame. |
row_vars |
The row variable, which will be printed with one level per line. If numeric, it will be converted to factor. If several row variables are provided, it's not possible to add any tab_vars. |
col_vars |
One column is printed for each level of each column variable. For numeric variables means are calculated, in a single column. |
tab_vars |
One subtable is made for each combination of levels of the tab variables. All tab variables are converted to factor. Leave empty to make a simple table. Not used when there are several row_vars. |
wt |
A weight variable, of class numeric. Leave empty for unweighted results. |
pct |
The type of percentages to calculate :
|
color |
Which measure to use for color helpers, as a single string.
The values are the measure names
How significance gates these colors is set separately by
|
color_signif |
How statistical significance gates the colors, as a single string.
|
test |
Set to |
anova |
Which F statistic to display for numeric column variables when the test is on: Welch's F (default, does not assume equal variances) or the classic pooled F. |
na |
The policy to adopt with missing values. It must be a single string.
|
lvs |
The levels of
|
cleannames |
By default, clean levels names, by removing prefix
numbers like "1-", and text in parenthesis. Set to |
ref_levels |
. |
levels_order |
. |
levels_collapse |
. |
shape |
. |
ref |
The reference cell to calculate differences and ratios (used
to print
|
ref2 |
With |
comp |
The comparison level : by subtables/groups, or for the whole table. |
ci |
What the confidence interval is anchored on – one
question, four answers. The GEOMETRY of the interval is not asked here: it
follows the comparison the table makes (set by
|
conf_level |
The confidence level, a single numeric between 0 and 1 — 0.95 by default. |
stars |
With |
design_effect |
For a WEIGHTED table, make the confidence intervals, the significance stars, the colour thresholds AND the p-values account for the unequal weighting (the exact flat survey-design variance) instead of using the raw number of respondents. Sets options(tabxplor.design_effect). Off by default; it moves every interval in the table, not only the p-value. |
ci_method_cell |
The proportion confidence-interval method for
|
ci_method_diff |
The proportion confidence-interval method for
|
ci_method_mean_diff |
The confidence-interval method for the
difference of numeric means (means with |
ci_method_mean_ratio |
The confidence-interval method for a ratio of
numeric means (means with |
tab_theme |
How the table is painted, in the results panel and in
every export. |
totaltab |
The total table, if there are subtables/groups (i.e. when
|
wrap_rows |
By default, rownames are wrapped when larger than 30 characters. |
wrap_cols |
By default, colnames are wrapped when larger than 12 characters. |
display |
What each cell shows. Every value here is a
|
n |
How many people the table is about: |
add_pct |
Set to |
subtext |
A character vector to print rows of legend under the table. |
digits |
The number of digits to print, as a single integer (0-6). In
R, |
n_min |
A pure display filter (0 = off). A row is dropped only when
its largest base across the column variables is below |
export_format |
The export file format: Excel ( |
exportExcel |
Press to export the table to the chosen format (the button label follows the format). |
export_dir |
The folder to save the exported file in. Blank or
|
export_filename |
The bare file name, with NO extension (the chosen format adds it). Illegal characters are removed automatically. Blank saves as "Table". |
resetPath |
Reset the folder and file name to their defaults (your Documents folder and "Table"). |
xl_replace |
"Set to |
A results object containing:
results$html_table |
a html | ||||
results$cache_state |
an image |
Regressions
jmvtabreg( data, outcome = NULL, predictors = NULL, tab_vars = NULL, wt = NULL, family = NULL, link = NULL, outcome_level = NULL, trials = NULL, effect = "auto", measure = "auto", empirical = TRUE, models = NULL, na = "drop_by_outcome", run_compare = FALSE, levels_order = NULL, levels_collapse = NULL, crosses = NULL, ref_levels = NULL, shape = NULL, multiplier = NULL, conf_level = 0.95, ci_method = "wald", stars = TRUE, color = "measure", color_signif = "grey_non_signif", display = "auto", n = "range", digits = "0", cleannames = TRUE, subtext = "", tab_theme = "light", wrap_rows = 35, wrap_cols = 15, export_format = "excel", exportExcel = FALSE, export_dir = "~/Documents", export_filename = "Reg_model", resetPath = FALSE, xl_check = FALSE, xl_replace = FALSE )jmvtabreg( data, outcome = NULL, predictors = NULL, tab_vars = NULL, wt = NULL, family = NULL, link = NULL, outcome_level = NULL, trials = NULL, effect = "auto", measure = "auto", empirical = TRUE, models = NULL, na = "drop_by_outcome", run_compare = FALSE, levels_order = NULL, levels_collapse = NULL, crosses = NULL, ref_levels = NULL, shape = NULL, multiplier = NULL, conf_level = 0.95, ci_method = "wald", stars = TRUE, color = "measure", color_signif = "grey_non_signif", display = "auto", n = "range", digits = "0", cleannames = TRUE, subtext = "", tab_theme = "light", wrap_rows = 35, wrap_cols = 15, export_format = "excel", exportExcel = FALSE, export_dir = "~/Documents", export_filename = "Reg_model", resetPath = FALSE, xl_check = FALSE, xl_replace = FALSE )
data |
A data.frame. |
outcome |
The outcome variable(s). One model is built per outcome. Set each outcome's family (and, for a binomial outcome, its modelled level or number of trials) in the Model table. |
predictors |
The explanatory variables of the model. Factors are shown one line per level (the reference level as the neutral value); numeric predictors as a single line. |
tab_vars |
A grouping variable. The same model is fitted within each of its levels and the tables are stacked (like tab_vars for crosstables). |
wt |
A survey weight variable. Switches to design-based estimation (scale-invariant sandwich standard errors). Leave empty for unweighted results. |
family |
. |
link |
WHICH MEASURE THE MODEL ESTIMATES – the only argument that
changes the model. A link IS a measure, so it takes the same words as
|
outcome_level |
. |
trials |
. |
effect |
WHERE THE NUMBER COMES FROM, once the model and the reported measure are fixed.
|
measure |
WHICH MEASURE IS REPORTED. It never changes the model: where
it is not the measure the model estimates (see
|
empirical |
Show the crude, unadjusted, single-predictor effect beside each model effect — the bivariate association that IS the modelised quantity when there is a single predictor, so the gap between the two is what adjustment changed. |
models |
. |
na |
"drop_by_outcome" (default) fits every model OF ONE OUTCOME on the same complete cases, which is what makes the observed columns comparable to the model beside them and lets the likelihood-ratio comparison run; "drop_by_model" gives each model its own complete cases (a model on a different population then gets no observed effect); "drop_all" shares one population across every outcome as well. |
run_compare |
. |
levels_order |
. |
levels_collapse |
. |
crosses |
. |
ref_levels |
. |
shape |
. |
multiplier |
. |
conf_level |
The confidence level for intervals and the significance stars. |
ci_method |
Wald intervals (also the only option for weighted models) or profile-likelihood intervals (unweighted binomial / poisson only; needs MASS). A profile interval is an output of the likelihood at one confidence level, so it cannot be cached: every change refits the models. |
stars |
Show per-cell significance stars (the colours read the confidence interval either way). |
color |
WHAT the effect cells are coloured by. The colour LADDER always comes from what the column estimates (an odds ratio is read on the odds-ratio scale, a beta on the standardized-difference one), so what is left to choose is what the estimate is compared TO.
|
color_signif |
How significance interacts with the colours: observed size + grey out non-significant cells, colour only the guaranteed (error-adjusted) effect, ignore significance. |
display |
The estimate-cell LAYOUT (never the estimand: a display may
fold in another quantity of the SAME fit, it can never change the fit). The
same named layouts |
n |
The column giving the number of observations behind each predictor
level: |
digits |
The minimum number of digits to print, as a single integer
(0-6): each measure keeps its own precision where that is finer (an odds
ratio reads at two decimals, a mean score at one). In R, |
cleannames |
Strip numeric prefixes from factor level labels. |
subtext |
A free note printed below the table. |
tab_theme |
How the table is painted, in the results panel and in
every export. |
wrap_rows |
. |
wrap_cols |
. |
export_format |
. |
exportExcel |
Press to export the table to the chosen format (the button label follows the format). |
export_dir |
The folder to save the exported file in. Blank or
|
export_filename |
The bare file name, with NO extension (the chosen format adds it). |
resetPath |
Reset the folder and file name to their defaults (your Documents folder and "Regression"). |
xl_check |
Excel export only: draw the model-check plots
( |
xl_replace |
"Set to |
A results object containing:
results$html_table |
a html | ||||
results$cache_state |
an image | ||||
results$compare_state |
an image |
tabxplor_tab around fmt columnsBuild a tabxplor_tab around fmt columns
new_tab( tabs = tibble::tibble(), subtext = "", test = new_test_tibble(), chi2 = NULL, meta = NULL, ..., class = character() ) new_grouped_tab( tabs = tibble::tibble(), groups, subtext = "", test = new_test_tibble(), chi2 = NULL, meta = NULL, ..., class = character() )new_tab( tabs = tibble::tibble(), subtext = "", test = new_test_tibble(), chi2 = NULL, meta = NULL, ..., class = character() ) new_grouped_tab( tabs = tibble::tibble(), groups, subtext = "", test = new_test_tibble(), chi2 = NULL, meta = NULL, ..., class = character() )
tabs |
A table, stored into a |
subtext |
The footer's text, as a template: one element per line, every
|
test |
A tidy tibble storing whole-table test results (Chi2 for factor columns,
ANOVA F for mean columns), filled by |
chi2 |
|
meta |
The table's metadata, as a single named list gathering (all optional,
|
... |
Needed to implement subclasses. |
class |
Needed to implement subclasses. |
groups |
The grouping data. |
A tibble of class tabxplor_tab.
A tibble of class tabxplor_grouped_tab.
A French national survey, used to show what adjustment does to a relationship: going to the
cinema is strongly patterned by occupation, and also by age – and the two are entangled. See the
Reading a regression article for the analysis. It also carries a real sampling weight (poids), so it
is the data set to try wt = on; see vignette("tabxplor-weights").
questionr_hdvquestionr_hdv
A tibble of 2 000 rows and 20 columns. The ones the article uses:
Went to the cinema in the last 12 months? "Oui" first.
Occupational qualification, 7 levels, "Cadre" (senior professional) first. 347 values are missing, as in the original.
Age in years, 18 to 97.
The survey's own sampling weight.
The rest describe the respondent (sexe, nivetud, occup, freres.soeurs), their views
(clso, relig, trav.imp, trav.satisf) and six more leisure activities (sport, cuisine,
bricol, lecture.bd, peche.chasse, hard.rock), plus heures.tv and id.
The complete hdv2003 data of the questionr package (Julien Barnier, Francois
Briatte and Joseph Larmarange), GPL (>= 2) – with thanks. It comes from the Histoire de vie
survey run in 2003 by INSEE, the French national statistics institute. tabxplor's copy changes
only the level order: every "Oui"/"Non" item reads "Oui" first, and qualif starts at "Cadre".
tab(questionr_hdv, qualif, cinema, pct = "row", na = "drop", color = "difference")tab(questionr_hdv, qualif, cinema, pct = "row", na = "drop", color = "difference")
A teaching companion, not a decision tool. Every verdict these panels illustrate is already a
row in the table's own footer, for every model column, with no plotting package installed (see the
stats argument of tab_reg()). This function exists to show what a violation looks like.
One call diagnoses every model in the table: one titled grid per model, drawing the panels its own
family allows. Pass a tab_reg() table — the data it was built from is usually found on its own
— or a fitted model directly.
reg_check_plots( x, data = NULL, check = "auto", predictors = NULL, ncol = NULL, facet_ncol = NULL, theme = NULL, lang = NULL, max_points = 2000L, nbins = 10L, conf = 0.95, seed = 20260810, ... )reg_check_plots( x, data = NULL, check = "auto", predictors = NULL, ncol = NULL, facet_ncol = NULL, theme = NULL, lang = NULL, max_points = 2000L, nbins = 10L, conf = 0.95, seed = 20260810, ... )
x |
A |
data |
The data frame or |
check |
Which panels to draw. |
predictors |
Optional: restrict the linearity panel to these continuous predictors. |
ncol |
Number of panel columns in the assembled grid (default: as square as it can be, 3 at most). |
facet_ncol |
Number of facet columns inside a panel (default: 2 for linearity, 4 for proportionality). |
theme |
|
lang |
Language of the titles and captions ( |
max_points |
Thin the raw-point layers to about this many observations; statistics and verdicts are always computed on the full data. |
nbins |
Bins of the linearity panel's observed curve (default 10). |
conf |
Confidence level of the Q-Q band. Default |
seed |
Seed of the randomised quantile residuals ( |
... |
Unused, for future extension. |
Invisibly, the assembled gtable — or, with several models, the named list of them, one
per model, all drawn on the current graphics device.
tab_reg() and its stats argument (the same checks as footer rows), and
forest_plot() for the RESULTS – its opposite contract: it reads the finished table and never
re-fits, where a model check always must.
# \donttest: building a multi-panel ggplot grid costs a few seconds of CPU. d <- forcats::gss_cat |> dplyr::mutate(married = factor(dplyr::if_else(marital == "Married", "Married", "Not married"))) if (requireNamespace("ggplot2", quietly = TRUE) && requireNamespace("gridExtra", quietly = TRUE)) { t <- tab_reg(d, "married", c("race", "age"), family = "binomial") reg_check_plots(t) }# \donttest: building a multi-panel ggplot grid costs a few seconds of CPU. d <- forcats::gss_cat |> dplyr::mutate(married = factor(dplyr::if_else(marital == "Married", "Married", "Not married"))) if (requireNamespace("ggplot2", quietly = TRUE) && requireNamespace("gridExtra", quietly = TRUE)) { t <- tab_reg(d, "married", c("race", "age"), family = "binomial") reg_check_plots(t) }
Shows the formula behind every column of a tab_reg() table — exactly what reached
stats::glm(), survey::svyglm(), nnet::multinom() or MASS::polr(). Use it to check what a
shape =, a trials = or a model formula really built.
reg_formulas(x)reg_formulas(x)
x |
A table built by |
One row per model: several outcomes give one each, a predictors list one per model. Two things
the list does not repeat: under tab_vars the same formula is fitted within each group, and
color = "between_groups" (or stats = "group_interaction") fits one extra pooled model for the footer
test only.
A summed score (trials =) is fitted on a success / failure pair, so its formula names the two
internal columns tabxplor builds for it (.gb_succ, .gb_fail, and .gb_trials in the offset of
the risk-ratio link).
The formula names the columns as the user wrote them, but a continuous predictor is fitted
anchored at its ref (its mean by default), and a shape = may have recoded it — neither
changes any effect, only what the Constant row means.
A tibble with one row per model: model (its name in the table), outcome, family (the
outcome family), link (the measure that model estimates — the word link = takes), fit
(the R call it was fitted with) and formula. A svyglm() row also means robust
(Huber-White) standard errors: survey's design-based variance IS the sandwich, which is why a
ratio or a difference on a binary outcome is fitted through it.
tab_reg(), reg_measures() (what an outcome can be modelled as).
d <- forcats::gss_cat d$married <- as.integer(d$marital == "Married") reg_formulas(tab_reg(d, "married", c("race", "age"), family = "binomial"))d <- forcats::gss_cat d$married <- as.integer(d$marital == "Married") reg_formulas(tab_reg(d, "married", c("race", "age"), family = "binomial"))
Lists what tab_reg() can report for one outcome: which models it could fit, and which measure
of deviation each of them yields. It reads the same runtime table the argument validator and the
error messages read, so what it prints is what the function does. The section below is the same
table for every kind of outcome, read without any data.
reg_measures(data, outcome, family = "auto", link = "auto")reg_measures(data, outcome, family = "auto", link = "auto")
data |
A data frame (or a |
outcome |
The outcome column name. |
family |
The model family. |
link |
Which measure the model estimates. |
The table has two blocks, because the grid factors:
one row per model you could fit — its link, and the measure that model's own coefficients
carry (effect = "conditional");
then the measures read off the model's predictions, which are the same whichever model you
fit — link reads "(any)" there.
So link is the choice that matters, and it decides only which measure comes with a
coefficient: everything else is available from any of them.
By default only each family's own model is listed — the one it fits unless told otherwise.
link = "all" adds the others, which are specialist choices, and marks the family's own with
base_link.
Only what can be built is listed. A measure this kind of outcome does not have simply has no row,
and the message says why (an odds ratio needs a probability to take the odds of). One state exists
only at run time: a link that does not converge on your data. tab_reg() says so and, for the
risk difference, falls back to the linear probability model.
A tibble of family (only when several are listed), link, measure, effect,
header (the column name it would produce) and reads_as (what that header's acronym means).
With link = "all", a base_link column says which model is the family's own (NA on the
prediction rows, which belong to no link in particular).
Generated from the package's own resolution table, so it cannot drift from what
tab_reg() builds. A measure that IS the model's own is read off its
coefficients; any other is computed from its predictions (effect = "marginal" or
"at_reference").
gaussian — a cell is a mean. Models: link = "difference", the default (linear regression); link = "ratio" (log-link mean regression (Poisson pseudo-likelihood, robust standard errors)). Reported: measure = "difference", "ratio", "raw_coefficient".
binomial — a cell is a percentage. Models: link = "odds_ratio", the default (logistic regression); link = "ratio" (modified Poisson regression); link = "difference" (additive-risk regression (identity link, robust standard errors)). Reported: measure = "ratio", "difference", "odds_ratio", "raw_coefficient".
poisson — a cell is a count. Models: link = "ratio", the default (Poisson regression). Reported: measure = "difference", "ratio", "raw_coefficient".
multinomial — a cell is a percentage. Models: link = "odds_ratio", the default (multinomial logistic regression). Reported: measure = "ratio", "difference", "odds_ratio", "raw_coefficient".
ordinal — a cell is a position on an ordered scale. Models: link = "odds_ratio", the default (ordinal logistic regression). Reported: measure = "difference", "ratio", "odds_ratio", "raw_coefficient".
tab_reg() to build the table, reg_formulas() to see the formula each column was
fitted with.
reg_measures(car_arrests, "released") reg_measures(car_salaries, "salary")reg_measures(car_arrests, "released") reg_measures(car_salaries, "salary")
Builds an integer score column counting, for each row, how many of the listed factors sit at
their first level (1 if so, 0 otherwise) – the score ranges 0 to length(vars_list). The
natural way to sum a battery of yes/no survey items into one score, feeding the grouped-binomial
outcome of tab_reg() (its trials argument).
score_from_lv1(data, name, vars_list)score_from_lv1(data, name, vars_list)
data |
A data.frame. |
name |
The name of the score variable to create (unquoted or a string); an existing column of that name is replaced. |
vars_list |
The factors to count, as a character vector. For each one only its first level counts (as 1); every other level, including missing values, counts as 0. |
The "first level" is levels(as.factor(x))[1]. Non-factor columns are coerced with
as.factor(); missing values are folded into an explicit "NA" level first (via
forcats::fct_na_value_to_level()), so NA never counts as the first level.
data with the integer score column name added (or replaced).
tab_reg() and its trials argument for modelling a summed score
as a grouped binomial; vignette("tabxplor"), section "Multiple-answer
questions", for a worked example.
data <- tibble::tibble(group = factor(c("G1", "G1", "G2", "G2", "G3", "G3")), a = factor(c("Oui", "Oui", "Oui", "Oui", "Non", "Oui")), b = factor(c("Oui", "Non", "Non", "Oui", "Non", "Oui")), c = factor(c("Oui", "Oui", "Non", "Non", "Oui", "Oui"))) data |> score_from_lv1("score", vars_list = c("a", "b", "c")) |> tab(group, score, digits = 1)data <- tibble::tibble(group = factor(c("G1", "G1", "G2", "G2", "G3", "G3")), a = factor(c("Oui", "Oui", "Oui", "Oui", "Non", "Oui")), b = factor(c("Oui", "Non", "Non", "Oui", "Non", "Oui")), c = factor(c("Oui", "Oui", "Non", "Non", "Oui", "Oui"))) data |> score_from_lv1("score", vars_list = c("a", "b", "c")) |> tab(group, score, digits = 1)
Names the columns whose cells carry a horizontal bar behind their figure — a bar chart inside the table, at no cost in width, in html and in Excel. Total and footer rows take none.
One reference per column: every bar in a column is a share of the same ceiling, or two bars
could not be compared. That ceiling is the column's own largest data cell by default, which is what
spreads the bars over the width available; max states it instead, so that two tables can be
read against each other.
It is a display intent, like a caption: the numbers are untouched, and a medium with nowhere to put a bar (the console, a pipe table) ignores it.
set_bars(x, cols, max = NULL) get_bars(x)set_bars(x, cols, max = NULL) get_bars(x)
x |
A |
cols |
Column names, or |
max |
The ceiling a full bar means, in the column's stored unit — a percentage is
stored between 0 and 1, so |
x, with its bar columns set (set_bars) ; a named vector of their ceilings,
NA where the column's largest is used, or NULL (get_bars).
new_tab() for the whole meta record.
t <- tab(forcats::gss_cat, race, marital, pct = "row") t <- set_bars(t, "Married") get_bars(t) # a full bar means 100 %, whatever the column holds get_bars(set_bars(t, "Married", max = 1))t <- tab(forcats::gss_cat, race, marital, pct = "row") t <- set_bars(t, "Married") get_bars(t) # a full bar means 100 %, whatever the column holds get_bars(set_bars(t, "Married", max = 1))
Records a caption/title on a tabxplor_tab that survives a dplyr pipeline (it is kept in the
table's meta$vars$caption, carried through every verb) and is read by the exporters
(tab_md, tab_kable, tab_xl) as the
table title, ahead of a regression table's auto-title, when the exporter's own caption=
argument is not supplied. get_caption() reads it back (NULL when none is stored).
set_caption(x, caption) get_caption(x)set_caption(x, caption) get_caption(x)
x |
A |
caption |
A single string, or |
x, with its stored caption set (set_caption) ; the caption or NULL
(get_caption).
Everything that decides what a coloured cell LOOKS like, and at which value it changes shade.
set_color_palette() sets the hues (and the console's light/dark theme); set_color_breaks()
sets the thresholds each measure is read on; get_color_style() and get_color_breaks() read
them back. All of them act globally, through options(), so one call at the top of a script
restyles every table it builds — see tabxplor-options. A single table can override the
thresholds with tab(color_breaks =).
Color breaks are a named list of the ten measure scales pct_diff,
pct_ratio, odds_ratio, mean_diff, mean_ratio, contrib,
zscore, adj_ratio, adj_diff and adj_diff_std. Each is
a vector of positive-only thresholds (the under-represented side is mirrored automatically), 1 to 4
values, one per color step.
Every default is the same ladder in another measure, read at ONE reference cell of 50 %: 5 / 10 /
20 / 30 percentage points is also 0.1 / 0.2 / 0.4 / 0.8 SD, x1.1 / x1.2 / x1.5 / x2 as a ratio and
x1.2 / x1.5 / x2 / x4 as an odds ratio – so a shade means the same size of deviation whichever
measure a table is read on. pct_diff colors percentage-point differences,
pct_ratio the relative risk, odds_ratio the odds ratio (color =
"odds_ratio"), mean_diff the standardized mean difference (Glass's delta) by
default (supply data-unit values for absolute coloring), mean_ratio the mean ratio,
contrib the chi2 contribution (in multiples of the mean cell contribution) and
zscore an absolute z scale (the adjusted standardized residual) – the absolute scale
color = "contrib" switches to under color_signif = "guaranteed_effect". Its default
c(1.96, 2.58, 3.89, 6) is written as conf_level_to_z(c(0.95, 0.99, 0.9999,
1 - 2e-9)), and its FIRST value is re-anchored to the significance threshold at print time, so
the remaining ones are read as spacings from it. adj_ratio, adj_diff and
adj_diff_std are the
tab_reg-only scales of color = "adjustment" / "between_groups" –
how far a modelled effect sits from the observed one (or from the reference group's). Which one a
column reads follows the estimate's own scale: adj_ratio for a multiplicative effect (odds /
risk ratio or ratio of means), adj_diff for a probability-scale marginal effect (in percentage points),
and adj_diff_std for an additive effect in the outcome's own units (a gaussian beta, a count
marginal effect), where the gap is divided by SD(Y) so the same threshold means the same thing
whatever unit the outcome is recorded in. An empty/NULL scale
drops that measure for its column type.
Two rules shape a default, and a custom one is free to break them. A ladder is MIRRORED unless the
quantity it grades is bounded above: a percentage ratio is capped at 1 / base, so a cell can
sit far below its reference and never far above it, and pct_ratio is stricter below
(list(over = c(1.1, 1.2, 1.5, 2), under = c(1.1, 1.25, 2, 4))) – a ratio of means
and a ratio of two estimates have no ceiling and stay symmetric. And a fill is read at a glance, so
on the BACKGROUND channel the two ratio scales keep their two loudest rungs only: with the default
color = TRUE the text grades every deviation and the background flags the ones whose
RELATIVE size is out of proportion.
set_color_palette( text_colors = NULL, text_colors_neg = NULL, background_colors = NULL, background_colors_neg = NULL, dark_text_colors = NULL, dark_text_colors_neg = NULL, dark_background_colors = NULL, dark_background_colors_neg = NULL, bg_legend_colors = NULL, bg_legend_colors_neg = NULL, theme = NULL ) set_color_style( type = c("text", "bg"), theme = NULL, html_24_bit = NULL, custom_palette = NULL ) get_color_style( mode = c("crayon", "color_code", "face"), type = NULL, theme = NULL, ... ) set_color_breaks(breaks = NULL, ...) get_color_breaks(brk, type = c("positive", "all"))set_color_palette( text_colors = NULL, text_colors_neg = NULL, background_colors = NULL, background_colors_neg = NULL, dark_text_colors = NULL, dark_text_colors_neg = NULL, dark_background_colors = NULL, dark_background_colors_neg = NULL, bg_legend_colors = NULL, bg_legend_colors_neg = NULL, theme = NULL ) set_color_style( type = c("text", "bg"), theme = NULL, html_24_bit = NULL, custom_palette = NULL ) get_color_style( mode = c("crayon", "color_code", "face"), type = NULL, theme = NULL, ... ) set_color_breaks(breaks = NULL, ...) get_color_breaks(brk, type = c("positive", "all"))
text_colors, text_colors_neg, background_colors, background_colors_neg
|
Light-theme palettes
(4 hex each): the text (font) and background (fill) colours for the over- ( |
dark_text_colors, dark_text_colors_neg, dark_background_colors, dark_background_colors_neg
|
The dark-theme counterparts (4 hex each). |
bg_legend_colors, bg_legend_colors_neg
|
(4 hex each) The FONT stand-in for
|
theme |
Which palette theme. In |
type |
Which palette, or which half of a break scale — the word means one thing per
function, and both are given here because they share this page. In |
html_24_bit |
|
custom_palette |
|
mode |
By default, |
... |
Scales passed individually and named, e.g.
|
breaks |
A named list of scales to set, e.g.
|
brk |
When missing, return the full named list of the ten break scales – the same shape
|
set_color_palette() customises the palette used to print tab. Each
palette is 4 hex codes ordered faint -> strong. Provide only the ones you want to change; the
OKLCH defaults are used otherwise. The ANSI styles are (re)built once, not per cell.
Sets the internal color palettes (invisibly) and the option
"tabxplor.color_style_theme".
A list of 8 terminal (ANSI) color-style functions, a vector of 8 color html codes, or
(mode = "face") the palette's typography record.
Sets the global option "tabxplor.color_breaks" (a named list of scales) and returns it invisibly.
The color breaks as a double vector or a list(over =, under =), or a named list
of these.
set_color_style(): Superseded by
set_color_palette().
Kept as a back-compat shim: type/theme still take effect (as options);
custom_palette maps its over/under colours onto the new 4+4 palette; html_24_bit
is inert (exports are always 24-bit).
get_color_style(): get the color palette as terminal (ANSI) style functions or html codes: an
8-element vector (4 over-represented intensities then 4 under-represented), indexed by the engine slot.
set_color_breaks(): set the breaks used to print colors.
get_color_breaks(): get the color breaks currently in use, in the canonical shape.
set_color_palette(text_colors = c("#02a5b3", "#0891c9", "#0267c7", "#300dfd")) set_color_breaks( pct_diff = c(0.05, 0.15, 0.3), pct_ratio = list(over = 2), mean_ratio = c(1.15, 2, 4), contrib = c(1, 2, 5) ) set_color_breaks(get_color_breaks()) # a no-op: the shape round-tripsset_color_palette(text_colors = c("#02a5b3", "#0891c9", "#0267c7", "#300dfd")) set_color_breaks( pct_diff = c(0.05, 0.15, 0.3), pct_ratio = list(over = 2), mean_ratio = c(1.15, 2, 4), contrib = c(1, 2, 5) ) set_color_breaks(get_color_breaks()) # a no-op: the shape round-trips
The generated legend names a measure with the discipline's own words — color = "contrib"
says contribution to Chi2. A table may legitimately grade the same ladder on another quantity: a
factorial axis has no chi-squared, and its cells' contribution is to the variance of the axis.
set_legend_words() re-states the words and changes nothing else, so the swatches, the
ladder, both registers, the publication palettes, the plot guide and every medium keep working —
the console included, which no exporter argument can reach.
Prefer it to writing a legend of your own: replacing the sentence (through
set_subtext) costs you the terse/prose pair and the publication palettes' wording.
set_legend_words(x, ...) get_legend_words(x)set_legend_words(x, ...) get_legend_words(x)
x |
A |
... |
One argument per measure ( |
The fields a table may re-state — naming only, never a number:
word — the short word (the console, a plot guide);
word_long — the same named in full, for the export footers; word_std /
word_long_std their SD-scale twins.
word_guar — the color_signif = "guaranteed_effect" head, a template
taking the confidence level ("%s%%-guaranteed contribution").
subject — the noun for what is graded, when it is not the cell itself.
ref — the baseline noun (the mean contribution), for a measure compared to
a concept rather than to a row of the table: the terse form brackets it with its
preposition and the prose one points at it bare, both from this one field. Give
ref_word / ref_phrase instead only where those two nouns genuinely differ.
Re-stating any of them on a measure whose reference is a category or a total is refused — there
the legend names what the table itself shows.
unit_word — the unit the thresholds are counted in.
lead_over / lead_under — the sentence each side of the ladder opens with,
as a template taking %1$s the subject, %2$s the reference and %3$s the
null value. Only %1$s is always there: a line names its baseline in full on its
first side and not again on its second, so %2$s comes back empty there — where the
baseline is the measure's own (a mean contribution, an axis), write it into the sentence rather
than interpolate it.
caveat — one sentence of honesty appended to the line.
An engine fact (raw, scale, sig_source, bounds) and a ladder glyph
(break_over, threshold_mult) are refused: a table attribute must never change a
number, and a column pulled out of its table must still colour identically.
Written in the language of the call — unlike the words tabxplor generates, which follow
lang = at render.
x, with its legend words set (set_legend_words) ; the named list of them, or
NULL (get_legend_words).
set_subtext() for the footer template, set_color_breaks() for the ladder itself.
t <- tab(forcats::gss_cat, race, marital, pct = "row", color = "contrib") cat(tab_footer_text(t), sep = "\n") t <- set_legend_words(t, contrib = "contribution to the axis variance") cat(tab_footer_text(t), sep = "\n")t <- tab(forcats::gss_cat, race, marital, pct = "row", color = "contrib") cat(tab_footer_text(t), sep = "\n") t <- set_legend_words(t, contrib = "contribution to the axis variance") cat(tab_footer_text(t), sep = "\n")
A table's footer text, as a template: everything tabxplor generates is a
<placeholder> and everything you write is a line, so the order of the lines is the order of
the footer. Re-order them and it re-orders; drop <legend> and no colour legend is
generated, in the console too.
A subtext naming no placeholder is simply appended to the template — which is what a
note has always done, so tab(subtext = "Field: GSS 2000") is unchanged. Writing one
placeholder on a line of its own takes the layout over: only what you name is printed.
An unknown <...> is not a placeholder and passes through verbatim (\< escapes a
literal <).
The template a producer writes names only what this table can say: no <weight> on an
unweighted table, no <model> outside a regression. What you read back is therefore what
prints, and the way to drop a line is to delete it.
A line opening on a short label and a colon ("Field: GSS 2000") has that label set in bold
in every medium; options(tabxplor.subtext_bold_label = FALSE) prints it as written.
set_subtext(x, subtext) get_subtext(x)set_subtext(x, subtext) get_subtext(x)
x |
A |
subtext |
A character vector, one element per line, or |
x, with its footer template set (set_subtext) ; the template, as a
character vector (get_subtext).
tab_footer_text() to see what the template prints, set_legend_words() to re-word the
generated legend, set_footer_tabs() for a table or a note under the whole block.
t <- tab(forcats::gss_cat, race, marital, pct = "row", color = "diff") get_subtext(t) # your own sentence, with tabxplor's own pieces inside it t <- set_subtext(t, c("<measure> (<ref>): <breaks>", "<stars>")) cat(tab_footer_text(t), sep = "\n")t <- tab(forcats::gss_cat, race, marital, pct = "row", color = "diff") get_subtext(t) # your own sentence, with tabxplor's own pieces inside it t <- set_subtext(t, c("<measure> (<ref>): <breaks>", "<stars>")) cat(tab_footer_text(t), sep = "\n")
Turn a number into the form you want to read it in: cut it into quantile groups or into bands at
the mean and one standard deviation either side (it becomes an ordinary factor), or transform it
and keep it a number. This is the same operation tab(shape =) and tab_reg()(shape =)
perform, exposed on its own vector, so a column you cut by hand is identical to one they cut.
shape_numeric_var(x, shape, w = NULL, name = NULL, ordered = TRUE)shape_numeric_var(x, shape, w = NULL, name = NULL, ordered = TRUE)
x |
A numeric vector. |
shape |
A single string, or a number of groups — see The shapes below. |
w |
Optional weights, the same length as |
name |
The variable's name, written onto the first level only ( |
ordered |
Whether the resulting factor is |
For a cut: a factor whose levels carry the real cut points and, in words, where each group
sits. For "log" / "sqrt": a numeric vector.
"log" and "sqrt" replace the values, so a crosstab column then shows the mean of the
logarithm — a different quantity from the logarithm of the mean, and smaller. tab() renames
the column for that reason (age becomes log_age), so no header promises the wrong quantity;
do the same if you shape a column by hand.
"linear": the number as it is — one slope in a model, one mean in a crosstab. The default for a column variable, and what shape is spelled out as when nothing is done.
"log": replace the variable by its logarithm — diminishing returns. Needs strictly positive values.
"sqrt": replace the variable by its square root. Needs non-negative values.
"sd_bands": four bands cut at the mean and one standard deviation either side. Each level names its own cut ([30,48) ; < mean), so the label can be checked against the interval beside it. The cut points mean the same thing across sub-samples of one variable, where quantile breaks move with each one; but the bands are NOT balanced, and on a skewed variable a landmark falling outside the data is dropped (an exponential variable gets three bands, not four).
"median": two groups of equal size, cut at the median — the coarsest reading of a number.
"terciles": three groups of equal size.
"quartiles": four groups of equal size. The counts are balanced, so every group answers on a comparable base.
"quintiles": five groups of equal size.
"deciles": ten groups of equal size. Reads a gradient, but ten rows need a large sample to keep each base usable.
"values_to_levels": one level per distinct value, in numeric order. Right for a counted number or a 1-7 scale; unreadable for a continuous one, which is what "auto" decides.
an integer k (2 to 20): k quantile groups of equal size.
tab() and tab_reg(), whose shape argument is this function applied once to the
whole population, before any sub-table or sub-model is split off.
age <- forcats::gss_cat$age table(shape_numeric_var(age, "sd_bands", name = "age")) table(shape_numeric_var(age, "quartiles"))age <- forcats::gss_cat$age table(shape_numeric_var(age, "sd_bands", name = "age")) table(shape_numeric_var(age, "quartiles"))
tab() builds a cross-table of one or several row variables by one or several column variables,
and colors the cells so the table is easy to read at a glance — in the R console, or exported
to Excel, HTML or Word. Cells can show counts, row or column percentages, or (for a numeric
column variable) means, optionally with differences, confidence intervals and tests.
The result is a tibble (of class tabxplor_tab), so every dplyr verb keeps working on
it.
New to the package? Four arguments are enough to begin — data, row_vars, col_vars and
pct — then add color when you want reading helpers. The
Introduction
(vignette("tabxplor")) works through them. Package-wide defaults are options(), listed at
tabxplor-options.
tab( data, row_vars, col_vars, tab_vars, wt, ..., pct = "no", color = "no", color_signif = "ignore", test = FALSE, na = "keep", levels = "all", cleannames = NULL, other_if_less_than = 0, ref = "auto", ref2 = "first", comp = "tab", ci = "auto", conf_level = NULL, stars = NULL, ci_method = NULL, anova = NULL, design_effect = NULL, totaltab = "line", common_totrow = FALSE, n = NULL, n_min = 0, add_pct = FALSE, subtext = "", caption = NULL, digits = 0, display = NULL, color_breaks = NULL, output_list = FALSE, spread_vars, filter )tab( data, row_vars, col_vars, tab_vars, wt, ..., pct = "no", color = "no", color_signif = "ignore", test = FALSE, na = "keep", levels = "all", cleannames = NULL, other_if_less_than = 0, ref = "auto", ref2 = "first", comp = "tab", ci = "auto", conf_level = NULL, stars = NULL, ci_method = NULL, anova = NULL, design_effect = NULL, totaltab = "line", common_totrow = FALSE, n = NULL, n_min = 0, add_pct = FALSE, subtext = "", caption = NULL, digits = 0, display = NULL, color_breaks = NULL, output_list = FALSE, spread_vars, filter )
data |
A data frame. |
row_vars |
<tidy-select> The row variable(s), printed with one
level per line, and the column variable(s), one level per column. A numeric variable
gives a single column of means. Each accepts one variable or several,
|
col_vars |
<tidy-select> The column variable(s) — see
|
tab_vars |
<tidy-select> Tab variables: one subtable per combination of their levels. Leave empty for a simple cross-table. |
wt |
A weight variable, of class numeric. Leave empty for unweighted results. |
... |
Arguments taken by name, and kept out of the signature. Past the variable
roles every argument must be named, and an unknown name is refused with a suggestion.
|
pct |
The percentages to calculate, as a single string or a vector the same length as
|
color |
Which measure of deviation to color — a deviation being how far a cell
sits from its reference, the measure which of the ways of expressing it you read.
The acronyms in brackets are permanent aliases, the same words |
color_signif |
How significance gates the color, as a single string:
With |
test |
Set to |
na |
The policy to adopt for missing values, as a single string :
|
levels |
The levels of |
cleannames |
Set to |
other_if_less_than |
When set to a positive integer, levels with less count than it will be merged into an "Others" level. |
ref |
The reference cell that differences and ratios are computed against:
One reference per |
ref2 |
The second reference level for odds ratios, needed only for a factor with
3 levels or more (the "OR of each level versus |
comp |
What each cell is compared with: |
ci |
What the confidence interval is anchored on. Its geometry is not asked here: it follows the comparison the table makes, so an odds-ratio table gets an odds-ratio interval.
|
conf_level |
The confidence level, as a single numeric between 0 and 1. |
stars |
Logical. With |
ci_method |
The interval method, one kind at a time, as ONE named vector – partial, like
A proportion ratio has only one method (Katz), so it is not a choice. |
anova |
Which one-way ANOVA F the p-value line shows for numeric
|
design_effect |
Whether the intervals, stars and colour thresholds of a weighted table
account for the weighting's own design effect instead of using the raw sample size.
|
totaltab |
The total table, when |
common_totrow |
With several |
n |
How many people this table is about. |
n_min |
A single positive integer (default |
add_pct |
Set to |
subtext |
A character vector to print rows of legend under the table. |
caption |
A title for the table. It is stored on the table, so it survives a
dplyr pipeline and travels into every export — html, Markdown, Excel,
|
digits |
The number of digits to print, as a single integer, or an integer vector the
same length as |
display |
What each value cell shows (text output only – the console, |
color_breaks |
A per-table override of the colour thresholds, in the form
|
output_list |
Logical (default |
spread_vars |
<tidy-select> The |
filter |
|
Ordered factors stay ordered through the whole pipeline, which is what lets
ref2 = "cumulative" pick its column variables by class. One consequence is worth knowing:
the synthetic "Total" and "NA" levels are appended after the real ones, so
on an ordered column they compare as the greatest. They are labels, not points on the scale.
Weights and survey designs. A weight (wt) weights the estimates; the intervals
still use the raw number of cases unless design_effect = TRUE. Pass a
survey::svydesign as data and strata, clusters, fpc and calibration reach
every interval, star and colour threshold. The footer always names what you got. See
Weighted and
survey data (vignette("tabxplor-weights")).
A tibble of class tabxplor_tab. Every numeric column is an
fmt vector holding all the data behind the number it shows; the row_vars
and tab_vars columns are factors. Any factor column you add later is treated as a
tab_vars and used for grouping, so keep added text columns as character.
With stars = TRUE and an interval anchored on the comparison (see ci), each cell
says how sure we can be that its deviation from the reference is real and not sampling noise:
* at the 10% level, ** at 5%, *** at 1%. The exact p-value is stored per
cell, readable with $pvalue or get_pvalue().
No separate test runs behind the scenes: a cell is significant exactly when the interval it
prints no longer contains zero, so the stars and the [inf; sup] bracket can never
contradict each other. Which classical test that amounts to follows ci_method, and the
table's legend names it. An absolute cell interval compares nothing, so it carries no stars.
tab_reg() (regression tables) and tab_counts() (pre-aggregated counts); the superseded
tab_num() (numeric variables) and tab_plain() (one bare cross-table).
tabxplor-display says what a cell can show; set_color_breaks() / set_color_palette()
customise the colours; tab_structure() reports what a finished table is and what accepts it.
Export it with tab_xl() (Excel), tab_kable() (HTML) or tab_md() (Markdown), and chart it
with forest_plot(). Package-wide defaults live in tabxplor-options.
color = "contrib" reads as a heatmap of the association pattern. For the specialist
contingency-table models built on top of it — quasi-independence, Goodman's RC association
models, UNIDIFF — see the logmult package
(https://cran.r-project.org/package=logmult).
# A simple cross-table of counts: tab(car_arrests, colour, released) # Row percentages, with the difference to the total coloured: tab(questionr_hdv, qualif, cinema, pct = "row", na = "drop", color = "difference") # One subtable per level of a third variable, and colour only what is significant: tab(questionr_hdv, qualif, cinema, sexe, pct = "row", na = "drop", color = "difference", color_signif = "grey_non_signif") # Several col_vars at once, mixing factors and numeric variables (means): tab(car_salaries, rank, c(discipline, salary, yrs.service), pct = "row") # `levels = "first"` keeps one column per variable: a compact summary of many items. tab(facto_tea, SPC, c(breakfast, evening, home), pct = "row", levels = "first") # Each cell's contribution to the table's variance, as in a correspondence analysis: tab(questionr_hdv, qualif, cinema, na = "drop", color = "contrib") # The result is a tibble, so every dplyr verb works on it. Keep the total rows last: tab(questionr_hdv, qualif, cinema, pct = "row", na = "drop") |> dplyr::arrange(is_totrow(dplyr::pick(dplyr::everything())), dplyr::desc(Oui))# A simple cross-table of counts: tab(car_arrests, colour, released) # Row percentages, with the difference to the total coloured: tab(questionr_hdv, qualif, cinema, pct = "row", na = "drop", color = "difference") # One subtable per level of a third variable, and colour only what is significant: tab(questionr_hdv, qualif, cinema, sexe, pct = "row", na = "drop", color = "difference", color_signif = "grey_non_signif") # Several col_vars at once, mixing factors and numeric variables (means): tab(car_salaries, rank, c(discipline, salary, yrs.service), pct = "row") # `levels = "first"` keeps one column per variable: a compact summary of many items. tab(facto_tea, SPC, c(breakfast, evening, home), pct = "row", levels = "first") # Each cell's contribution to the table's variance, as in a correspondence analysis: tab(questionr_hdv, qualif, cinema, na = "drop", color = "contrib") # The result is a tibble, so every dplyr verb works on it. Keep the total rows last: tab(questionr_hdv, qualif, cinema, pct = "row", na = "drop") |> dplyr::arrange(is_totrow(dplyr::pick(dplyr::everything())), dplyr::desc(Oui))
fmt column of a table, and what it carriesOne row per numeric (tabxplor_fmt) column, with the per-column attributes that decide what it
shows, what it estimates, how it is coloured and how its confidence interval was computed. The
column-axis companion of tab_structure(), which describes the table as a whole.
tab_columns(x)tab_columns(x)
x |
A |
A tibble, one row per fmt column:
columnthe column name.
col_var, col_group
the column variable, and the sub-population its block belongs to
("" when the table was never spread).
scale, pct_type
what the column estimates, and on which percentage base.
displaythe display template(s) its cells carry.
ref, comp_all, totcol, refcol
the comparison model: which baseline, whether it compares across sub-tables, and whether this column is a total or the reference.
color, color_bg, color_signif
the colour measure of each channel and the significance policy.
conf_level, degf, basis, ci_method
how this column's interval was computed — the
level, the degrees of freedom it is referred to (NA = the normal quantile), whether it rests
on the raw count, the weights or the survey design, and by which method.
model_family, role
for a tab_reg() table: the column's model family, and whether it
holds the model estimate ("model") or its observed counterpart ("emp").
tab_structure() for the table's own structure; fmt_attr() to read or write one attribute;
fmt() for what each attribute means.
t <- tab(forcats::gss_cat, marital, race, pct = "row", ci = "ref") tab_columns(t)t <- tab(forcats::gss_cat, marital, race, pct = "row", ci = "ref") tab_columns(t)
Bind a list of tables into one
tab_compact(tabs)tab_compact(tabs)
tabs |
A |
A tabxplor_tab
forcats::gss_cat |> tab(c(race, rincome), marital, pct = "row", color = "difference", output_list = TRUE) |> tab_compact()forcats::gss_cat |> tab(c(race, rincome), marital, pct = "row", color = "difference", output_list = TRUE) |> tab_compact()
tab_counts() builds the same color-coded cross-table as tab(), but from data that is
already cross-tabulated — a dplyr::count() result, a contingency table, or a published
table of counts or percentages — instead of microdata (one row per individual). Percentages,
differences, confidence intervals, chi-squared, colors and totals are all computed from the
counts, and the result is identical to the table tab() would build from the microdata behind
them.
It accepts four input shapes:
Long tidy counts (the default): one row per row_var col_var (
tab_vars) combination, with the count in counts (and the weighted count in wt_counts).
A wide data.frame: a label (row_var) column plus one column per col_var level —
select those level columns with cols and name the column variable with col_name.
A table / xtabs / matrix object: melted automatically, the row and column variables
read from the dimnames (or set with row_var / col_var).
Frequencies + base N: the wide shape, plus input = "pct" and base (the column of row
sample sizes); the integer counts are rebuilt from the percentages and the base.
With weighted data, give the real (unweighted) count in counts and the weighted count in
wt_counts: estimates use the weighted counts, while confidence intervals and tests use the
real unweighted sample size. Counts that are not whole numbers (weighted-only or frequency-only
input) disable confidence intervals and chi-squared, with a message.
tab_counts( data, row_var, col_var, tab_vars, counts, wt_counts, cols, col_name = "variable", base, input = c("counts", "pct"), ... )tab_counts( data, row_var, col_var, tab_vars, counts, wt_counts, cols, col_name = "variable", base, input = c("counts", "pct"), ... )
data |
A data frame. |
row_var, col_var
|
|
tab_vars |
<tidy-select> Tab variables: one subtable per combination of their levels. Leave empty for a simple cross-table. |
counts |
The column holding the unweighted count for each cell (long tidy shape). |
wt_counts |
Optional column holding the weighted count for each cell. Leave empty for an unweighted table. |
cols |
< |
col_name |
Name of the (synthesised) column variable when |
base |
For |
input |
|
... |
Every other argument of |
A tabxplor_tab (or tabxplor_grouped_tab when tab_vars are provided).
# Long tidy counts (as from dplyr::count()) reproduce the microdata table : counts <- dplyr::count(forcats::gss_cat, marital, race) tab_counts(counts, marital, race, counts = n, pct = "row") # tab(forcats::gss_cat, marital, race, pct = "row") # identical # A contingency table object : tab_counts(table(forcats::gss_cat$marital, forcats::gss_cat$race), pct = "row") # A wide data.frame of counts : wide <- tidyr::pivot_wider(counts, names_from = race, values_from = n) tab_counts(wide, row_var = marital, cols = c(Other, Black, White), col_name = "race", pct = "row")# Long tidy counts (as from dplyr::count()) reproduce the microdata table : counts <- dplyr::count(forcats::gss_cat, marital, race) tab_counts(counts, marital, race, counts = n, pct = "row") # tab(forcats::gss_cat, marital, race, pct = "row") # identical # A contingency table object : tab_counts(table(forcats::gss_cat$marital, forcats::gss_cat$race), pct = "row") # A wide data.frame of counts : wide <- tidyr::pivot_wider(counts, names_from = race, values_from = n) tab_counts(wide, row_var = marital, cols = c(Other, Black, White), col_name = "race", pct = "row")
The CSS that colours tabxplor tables. It is a constant – a pure function of the colour palette,
the channel type and the theme – so it does not take a table: one stylesheet styles every table in a
document, whatever their color_breaks.
tab_css( theme = NULL, format = c("html", "md"), style_tag = TRUE, file = NULL, print_rules = NULL, ... )tab_css( theme = NULL, format = c("html", "md"), style_tag = TRUE, file = NULL, print_rules = NULL, ... )
theme |
|
format |
Which output the stylesheet is for, in |
style_tag |
Wrap the CSS in a |
file |
Optional path to write to instead of returning. |
print_rules |
Also emit a black-and-white publication palette inside an |
... |
Retired arguments, accepted and ignored with a deprecation message since 2.0.0
( |
Cells carry classes named after the palette slot (.p1-.p4 over-represented text, .m1-.m4
under-represented text, .o1-.o4 / .u1-.u4 for the background channel), so tab_html() and
tab_md() share one vocabulary.
The CSS, invisibly when file is given. Printed as-is by knitr with results = "asis".
Self-contained (the default). tab_html(css = TRUE) and tab_md(css = TRUE) inline the
stylesheet with the table, so a single file works anywhere (the RStudio/Positron Viewer, jamovi, a
standalone .html). Nothing to do.
Once per document. In an .Rmd/.qmd with many tables, emit it once and let every table reuse
it:
```{r, results = "asis"}
options(tabxplor.tab_kable_css = FALSE)
tab_css(theme = "auto")
```
Every later tab_html() then emits classes only. Two things to know: with css = FALSE and no
tab_css() call the tables render uncoloured; and one stylesheet means one colour theme for the
whole document. A black-and-white table (theme = "print_ready" or a publication palette on the
table's own call) still renders as such under it: every stylesheet carries the publication palettes,
scoped to the tables that wear them.
Nothing is written inline on a cell, so any of the look can be overridden by adding your own
rules after the stylesheet – no !important needed. The cell colour classes are also emitted
scoped (.tabxplor-tab .p1) so they survive host pages that style table cells themselves, such as
Bootstrap-based sites including pkgdown. Column widths in particular are left to the browser, which
sizes each column to its content; to pin one, style its role:
.tabxplor-tab .tx-rv { min-width: 10em; } /* the row-variable levels column */
.tabxplor-tab .tx-tot { min-width: 5.5em; } /* total columns */
.tabxplor-tab .tx-num { min-width: 4em; } /* every number column */
The roles a cell can carry: .tx-l/.tx-r (alignment), .tx-num (numbers), .tx-rv (the
row-variable levels column), .tx-tot (total columns), .tx-bl/.tx-br (side borders),
.tx-b (bold), .tx-lbl/.tx-vname (a variable name spanning its block), .tx-pill (a
background-coloured value), .tx-span (the variable-name header row), .tx-foot (the footnote).
Rows carry .tx-bt/.tx-bb/.tx-bb2 (top / bottom / thick-bottom rules).
Each html table is wrapped in a .tx-scrollbox, which scrolls it sideways rather than let it
widen the page. Its title stays outside, so it does not scroll away, and the @media print block
lifts the clip (a printer has no scrollbar). To let a table widen the page on screen too:
.tx-scrollbox { overflow-x: visible; max-width: none; }.
A greyscale print loses colour entirely — both direction ramps become the same grey — so
these palettes say the same thing with something else. theme = "print_ready"
is the one to reach for: it picks per table, the marks for a cross-table and the emphasis
ladder for a regression, whose cells already carry their own direction symbol. Name one
yourself to override that. They share ONE grey fill ramp (a background colour measure keeps
carrying its magnitude) and differ in the text channel:
"print_minimalistic"direction by underline (over) and italic (under); magnitude by an ink ladder.
"print_emphasis"magnitude by an emphasis ladder (bold, then underline, then double underline) in pure black; direction by the cell's own measure symbol, plus italic under the null.
"print_marks"magnitude and direction by a repeated superscript mark after the value (no significance stars: the marks take their place, do not use with tab_reg()).
In all of them a non-significant cell is greyed out, and the significance stars stay — except
under "print_marks", where the marks take their place (one run of symbols after a
value, not two). "bw" is a synonym of "print_minimalistic".
One caveat, and only for a document that emits tab_css() once and renders
its tables with css = FALSE: a stylesheet is table-independent, so it carries ONE of
them. A cross-table is fine whatever it carries (its marks are cell text), but a regression's
ladder is css and nothing else — name it there, tab_css(theme = "print_emphasis").
tab_html(), tab_md(), set_color_palette(), set_color_breaks()
cat(tab_css(theme = "auto")) cat(tab_css(format = "md", style_tag = FALSE)) # the markdown flavourcat(tab_css(theme = "auto")) cat(tab_css(format = "md", style_tag = FALSE)) # the markdown flavour
One entry point over the format-specific exporters tab_html (HTML),
tab_md (Markdown), tab_xl (Excel) and forest_plot
(a chart of the estimates). They share one set of display-option names and defaults;
tab_export() forwards them and passes any format-specific argument through ....
tab_export( x, format = c("html", "md", "xl", "forest"), path = NULL, theme = NULL, color = TRUE, color_legend = TRUE, lang = NULL, transpose = FALSE, caption = NULL, var_names = NULL, ... )tab_export( x, format = c("html", "md", "xl", "forest"), path = NULL, theme = NULL, color = TRUE, color_legend = TRUE, lang = NULL, transpose = FALSE, caption = NULL, var_names = NULL, ... )
x |
A table made with |
format |
One of |
path |
Optional output file. For |
theme |
By default ( |
color |
Set to |
color_legend |
Print the colour legend below the table (with the subtext). |
lang |
Colour-legend language: |
transpose |
Set to |
caption |
A single caption / title for the table. |
var_names |
Which variable names to write beside the table: |
... |
Format-specific arguments passed to the underlying exporter. Retired arguments
( |
Each exporter is also callable on its own, which reads better in a pipe
(x |> tab_xl()); use tab_export() when the format comes from a variable.
The value of the underlying exporter: an HTML/knitr object ("html"), a markdown
string ("md"), x invisibly with the Excel file written ("xl"), or a
ggplot ("forest").
tabs <- tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") tab_export(tabs, "md")tabs <- tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") tab_export(tabs, "md")
The HTML exporter behind tab_export: tab_export(x, format = "html") calls this, and
tab_kable() is a permanent alias of tab_html(). Use it directly for HTML-specific arguments.
tab_html( tabs, theme = NULL, color = TRUE, tooltips = NULL, popover = NULL, color_legend = TRUE, lang = NULL, caption = NULL, transpose = FALSE, var_names = NULL, get_data = FALSE, cells = NULL, wrap_rows = 35, wrap_cols = 15, whitespace_only = TRUE, css = NULL, ... ) tab_kable( tabs, theme = NULL, color = TRUE, tooltips = NULL, popover = NULL, color_legend = TRUE, lang = NULL, caption = NULL, transpose = FALSE, var_names = NULL, get_data = FALSE, cells = NULL, wrap_rows = 35, wrap_cols = 15, whitespace_only = TRUE, css = NULL, ... )tab_html( tabs, theme = NULL, color = TRUE, tooltips = NULL, popover = NULL, color_legend = TRUE, lang = NULL, caption = NULL, transpose = FALSE, var_names = NULL, get_data = FALSE, cells = NULL, wrap_rows = 35, wrap_cols = 15, whitespace_only = TRUE, css = NULL, ... ) tab_kable( tabs, theme = NULL, color = TRUE, tooltips = NULL, popover = NULL, color_legend = TRUE, lang = NULL, caption = NULL, transpose = FALSE, var_names = NULL, get_data = FALSE, cells = NULL, wrap_rows = 35, wrap_cols = 15, whitespace_only = TRUE, css = NULL, ... )
tabs |
A table made with |
theme |
By default (
Defaults to
|
color |
Set to |
tooltips |
By default, takes |
popover |
By default, takes |
color_legend |
Print the colour legend below the table (with the subtext). |
lang |
Colour-legend language: |
caption |
The table caption. For formatting, you need to use a |
transpose |
Set to |
var_names |
Which variable names to write beside the table: |
get_data |
Get the transformed data instead of the html table. |
cells |
The write side of |
wrap_rows |
Row labels are wrapped past this width (35 characters by default). |
wrap_cols |
Column headers are wrapped past this width (15 characters by default), at the seams a
compound name is built from ( |
whitespace_only |
Set to |
css |
Inline the stylesheet with the table, so the output is
self-contained (default, from |
... |
Retired arguments, accepted and ignored with a deprecation message since 2.0.0:
|
tab_kable() is a permanent alias of tab_html() – the two are identical. tab_html()
names the output (an HTML table); tab_kable() is the name it had when kableExtra rendered it.
A html table. Printing it opens it in the Viewer, on a page painted to match the table –
so a theme = "dark" table no longer sits in a white pane. Everything the cell has no room for –
the confidence interval, the exact p-value, the other ways of reading the same comparison
(difference, ratio, odds ratio), the chi-squared contribution and the base count – is one hover
away, each line named after the field it shows.
tabs <- tab(forcats::gss_cat, race, marital, year, pct = "row", color = "difference") tab_html(tabs, theme = "light")tabs <- tab(forcats::gss_cat, race, marital, year, pct = "row", color = "difference") tab_html(tabs, theme = "light")
Superseded (2.0.0) by tab(), the unified entry point: it accepts several row_vars /
col_vars and merges them into one table by default (output_list = TRUE gives the list shape
tab_many() returns).
tab_many() forwards everything to tab(), translating the five renamed arguments:
tab_many() |
tab() |
chi2 = TRUE |
test = TRUE |
totrow = FALSE |
tot = "col" |
totcol = "no" |
tot = "row" |
compact = TRUE |
output_list = FALSE |
na_drop_all = c(a, b) |
filter = !is.na(a) & !is.na(b)
|
Everything else keeps its name and meaning — see tab().
tab_many( data, row_vars, col_vars, tab_vars, wt, ..., chi2, totrow, totcol, compact, na_drop_all, filter )tab_many( data, row_vars, col_vars, tab_vars, wt, ..., chi2, totrow, totcol, compact, na_drop_all, filter )
data |
A data frame, or a |
row_vars, col_vars, tab_vars, wt
|
The variable roles — see |
... |
Passed on to |
chi2 |
|
totrow, totcol
|
|
compact |
|
na_drop_all |
|
filter |
|
What tab() returns: a tabxplor_tab (a tabxplor_grouped_tab with
tab_vars), or a tabxplor_tabs list under output_list = TRUE / compact = FALSE.
# Make a summary table with many col_vars, showing only one specific level : library(dplyr) first_lvs <- c("Married", "$25000 or more", "Strong republican", "Protestant") data <- forcats::gss_cat |> mutate(across( where(is.factor), ~ forcats::fct_relevel(., first_lvs[first_lvs %in% levels(.)]) )) tab_many(data, race, c(marital, rincome, partyid, relig, age, tvhours), levels = "first", pct = "row", test = TRUE, color = "auto") # Can be used with map and tribble to program several tables with different parameters # all at once, in a readable way: library(purrr) library(tibble) pmap( tribble( ~row_vars, ~col_vars , ~pct , ~filter , ~subtext , "race" , "marital" , "row", NULL , "Source: GSS 2000-2014", "relig" , c("race", "age"), "row", "year %in% 2000:2010", "Source: GSS 2000-2010", NA_character_, "race" , "no" , NULL , "Source: GSS 2000-2014", ), .f = tab_many, data = forcats::gss_cat, color = "auto", test = TRUE)# Make a summary table with many col_vars, showing only one specific level : library(dplyr) first_lvs <- c("Married", "$25000 or more", "Strong republican", "Protestant") data <- forcats::gss_cat |> mutate(across( where(is.factor), ~ forcats::fct_relevel(., first_lvs[first_lvs %in% levels(.)]) )) tab_many(data, race, c(marital, rincome, partyid, relig, age, tvhours), levels = "first", pct = "row", test = TRUE, color = "auto") # Can be used with map and tribble to program several tables with different parameters # all at once, in a readable way: library(purrr) library(tibble) pmap( tribble( ~row_vars, ~col_vars , ~pct , ~filter , ~subtext , "race" , "marital" , "row", NULL , "Source: GSS 2000-2014", "relig" , c("race", "age"), "row", "year %in% 2000:2010", "Source: GSS 2000-2010", NA_character_, "race" , "no" , NULL , "Source: GSS 2000-2014", ), .f = tab_many, data = forcats::gss_cat, color = "auto", test = TRUE)
The Markdown exporter behind tab_export: tab_export(x, format = "md") calls this.
tab_md( tabs, bold_references = TRUE, special_formatting = TRUE, wrap_rows = NULL, subtext = TRUE, color = TRUE, color_legend = TRUE, lang = NULL, theme = NULL, caption = NULL, transpose = FALSE, var_names = NULL, css = NULL, clipboard = FALSE, file = NULL, print = NULL, title = lifecycle::deprecated(), col_var_names = lifecycle::deprecated(), ... )tab_md( tabs, bold_references = TRUE, special_formatting = TRUE, wrap_rows = NULL, subtext = TRUE, color = TRUE, color_legend = TRUE, lang = NULL, theme = NULL, caption = NULL, transpose = FALSE, var_names = NULL, css = NULL, clipboard = FALSE, file = NULL, print = NULL, title = lifecycle::deprecated(), col_var_names = lifecycle::deprecated(), ... )
tabs |
A table made with |
bold_references |
Bold reference/total rows with markdown |
special_formatting |
Passed to |
wrap_rows |
Max width for row labels before truncation. |
subtext |
Print chi2/footnotes below the table. |
color |
When |
color_legend |
Print the colour legend below the table (with the subtext). |
lang |
Colour-legend language: |
theme |
Colour palette selector (as in |
caption |
Optional table caption, rendered as a pandoc caption line |
transpose |
Set to |
var_names |
Which variable names to write beside the table: |
css |
Prepend an inline |
clipboard |
Copy output to clipboard via |
file |
Path to write the markdown to a file. |
print |
By default ( |
title |
|
col_var_names |
|
... |
Retired arguments, accepted and ignored with a deprecation message since 2.0.0
( |
A tabxplor_md: the markdown as a character string, which prints as the text it is
and reaches a knitted document raw.
tab(forcats::gss_cat, race, marital, pct = "row") |> tab_md() tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") |> tab_md() tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") |> dplyr::mutate(dplyr::across(dplyr::where(is_fmt), ~set_display(., "diff"))) |> tab_md()tab(forcats::gss_cat, race, marital, pct = "row") |> tab_md() tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") |> tab_md() tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") |> dplyr::mutate(dplyr::across(dplyr::where(is_fmt), ~set_display(., "diff"))) |> tab_md()
A small grid of already-rendered character columns, printed under a table in the aside ink: a
glossary, a range, a set of diagnostics — something that belongs to the table without being a row
of it. Attach it with set_footer_tabs, beside (or instead of) a real table.
A plain data.frame passed to set_footer_tabs() already renders as a note, its own
names as headers, everything left-aligned. tab_note() is for when that is not enough.
tab_note( df, headers = NULL, align = NULL, grey = NULL, note = character(0), kind = NULL )tab_note( df, headers = NULL, align = NULL, grey = NULL, note = character(0), kind = NULL )
df |
A data.frame of character columns, already formatted. |
headers |
Column titles; defaults to |
align |
One of |
grey |
One logical per row: a row to render in the dimmer aside ink (a result the note itself
marks as not to be read). |
note |
One or more lines printed under the grid, smaller still — what a cell cannot say for itself. |
kind |
Per column, |
A tabxplor_note.
set_footer_tabs() to attach one, set_subtext() for the footer's text.
n <- tab_note(data.frame(axis = c("1", "2"), variance = c("9.9%", "7.2%")), headers = c("Axis", "% variance"), align = c("left", "right")) set_footer_tabs(tab(forcats::gss_cat, race, marital, pct = "row"), list("Axes" = n))n <- tab_note(data.frame(axis = c("1", "2"), variance = c("9.9%", "7.2%")), headers = c("Axis", "% variance"), align = c("left", "right")) set_footer_tabs(tab(forcats::gss_cat, race, marital, pct = "row"), list("Axes" = n))
Cross categorical variables with numeric ones, and get a table of means. Superseded by
tab(), which builds the same table whenever col_vars holds numeric variables – and
everything around it (both kinds of variable at once, colours, totals, tests). It stays the
smallest entry point into the numeric aggregate core, and takes the same arguments resolved
by the same rules, so its numbers agree with tab()'s cell for cell.
tab_num( data, row_var, col_vars, tab_vars, wt, ..., num = FALSE, df = FALSE, .fine = NULL, .by_table = FALSE )tab_num( data, row_var, col_vars, tab_vars, wt, ..., num = FALSE, df = FALSE, .fine = NULL, .by_table = FALSE )
data |
A data frame. |
row_var |
|
col_vars |
<tidy-select> The column variable(s) — see
|
tab_vars |
<tidy-select> Tab variables: one subtable per combination of their levels. Leave empty for a simple cross-table. |
wt |
A weight variable, of class numeric. Leave empty for unweighted results. |
... |
Every other argument of |
num |
Set to |
df |
Set to |
.fine, .by_table
|
Internal. |
A tibble of class tabxplor_tab. If ... (tab_vars)
are provided, a tab of class tabxplor_grouped_tab.
All non-text columns are fmt vectors of class tabxplor_fmt,
storing all the data necessary to print formats and colors. Columns with row_var
and tab_vars are of class factor : every added factor will be
considered as a tab_vars and used for grouping. To add text columns without
using them in calculations, be sure they are of class character.
data <- dplyr::storms |> dplyr::filter(!is.na(wind)) tab_num(data, category, wind, tot = "row", color = "difference", color_signif = "guaranteed_effect")data <- dplyr::storms |> dplyr::filter(!is.na(wind)) tab_num(data, category, wind, tot = "row", color = "difference", color_signif = "guaranteed_effect")
Shuts down the persistent mirai daemons tabxplor starts under
options(tabxplor.parallel = ). The pool is otherwise reused for the whole session and
cleaned up when the package is unloaded; call this to release the workers earlier.
tab_parallel_stop()tab_parallel_stop()
invisible(NULL), called for its side effect.
tabxplor-options for tabxplor.parallel, the switch that starts the pool.
# after options(tabxplor.parallel = TRUE) tab_parallel_stop()# after options(tabxplor.parallel = TRUE) tab_parallel_stop()
The markdown grid without the markup: one GFM pipe table, its unit line kept (<col%>,
<var>), no colour spans, no footer and no stylesheet. It is what the console prints under a
table for each of its subordinate tables (set_footer_tabs), the same shape a regression's
shape table takes there — a grid one can read as text and paste anywhere.
It is tab_md with three arguments fixed, not a second renderer: a pipe table that
drifted from the markdown export would be a second answer to one question.
tab_pipe(tabs, ...)tab_pipe(tabs, ...)
tabs |
A |
... |
Passed to |
A character vector, one element per line.
cat(tab_pipe(tab(forcats::gss_cat, race, marital, pct = "row")), sep = "\n")cat(tab_pipe(tab(forcats::gss_cat, race, marital, pct = "row")), sep = "\n")
One bare cross-table of counts or percentages, from ONE row variable and ONE column variable.
Superseded by tab(), which does the same and everything around it (several variables, colours,
totals, tests) – but it stays the smallest entry point into the aggregate core, and takes the
same ci / ci_method / conf_level / stars / display arguments, resolved by the same
rules, so its numbers agree with tab()'s cell for cell.
tab_plain( data, row_var, col_var, tab_vars, wt, ..., num = FALSE, df = FALSE, .fine = NULL, .by_table = FALSE )tab_plain( data, row_var, col_var, tab_vars, wt, ..., num = FALSE, df = FALSE, .fine = NULL, .by_table = FALSE )
data |
A data frame. |
row_var, col_var
|
|
tab_vars |
<tidy-select> Tab variables: one subtable per combination of their levels. Leave empty for a simple cross-table. |
wt |
A weight variable, of class numeric. Leave empty for unweighted results. |
... |
Every other argument of |
num |
Set to |
df |
Set to |
.fine, .by_table
|
Internal. |
A tibble of class tabxplor_tab. If ... (tab_vars)
are provided, a tab of class tabxplor_grouped_tab.
All non-text columns are fmt vectors of class tabxplor_fmt,
storing all the data necessary to print formats and colors. Columns with row_var
and tab_vars are of class factor : every added factor will be
considered as a tab_vars and used for grouping. To add text columns without
using them in calculations, be sure they are of class character.
# the leaf builds the cells AND their intervals: `ci` is resolved here exactly as in tab(), # so tab_plain(ci = "ref") and tab(ci = "ref") agree cell for cell. dplyr::starwars |> tab_plain(sex, hair_color, tot = c("row", "col"), pct = "row", ci = "ref", color = "difference", color_signif = "grey_non_signif")# the leaf builds the cells AND their intervals: `ci` is resolved here exactly as in tab(), # so tab_plain(ci = "ref") and tab(ci = "ref") agree cell for cell. dplyr::starwars |> tab_plain(sex, hair_color, tot = c("row", "col"), pct = "row", ci = "ref", color = "difference", color_signif = "grey_non_signif")
Fits one regression model per column and returns a tabxplor table of the per-family effect
measure — a linear mean difference (gaussian), odds ratios (binomial), ratios of
means (poisson counts), one odds-ratio column per outcome category (nominal 3+ level), a
cumulative odds ratio (ordinal) — one row per predictor level, grouped by predictor, with
the observed (crude) effect beside each adjusted one. Each cell stores its estimate, interval
and p-value, so the table prints with stars, greys what is not significant, and exports like any
tabxplor crosstab.
tab_reg( data, outcome, predictors = NULL, tab_vars = NULL, wt = NULL, family = "auto", link = "auto", measure = "auto", effect = "auto", outcome_level = NULL, trials = NULL, empirical = TRUE, n = NULL, color = "measure", color_signif = NULL, stars = TRUE, ref = NULL, multiplier = "2sd", shape = NULL, stats = "auto", conf_level = NULL, na = c("drop_by_outcome", "drop_by_model", "drop_all", "keep_for_predictors"), display = NULL, digits = 0, cleannames = NULL, subtext = "", caption = NULL, ... )tab_reg( data, outcome, predictors = NULL, tab_vars = NULL, wt = NULL, family = "auto", link = "auto", measure = "auto", effect = "auto", outcome_level = NULL, trials = NULL, empirical = TRUE, n = NULL, color = "measure", color_signif = NULL, stars = TRUE, ref = NULL, multiplier = "2sd", shape = NULL, stats = "auto", conf_level = NULL, na = c("drop_by_outcome", "drop_by_model", "drop_all", "keep_for_predictors"), display = NULL, digits = 0, cleannames = NULL, subtext = "", caption = NULL, ... )
data |
A data frame, or a prebuilt survey design ( |
outcome |
< |
predictors |
<
|
tab_vars |
< |
wt |
< |
family |
The model family, resolved per outcome so several outcomes with different
families can share one table. It answers one question — what kind of number the outcome is — and never picks a link
behind your back: on a binary outcome |
link |
Which measure the model estimates — the only argument that changes the model.
A link is a measure (the one a model gives you directly), so it takes
Reach for it when you want the model's coefficient to be that measure; to report a measure
without changing the model, set |
measure |
Which measure of deviation is reported — a deviation being how far a group
sits from the reference, the measure which of the ways of expressing it you read. The one
argument most readers ever set, and the one that never changes the model.
On an ordered outcome the first three read the whole predicted distribution rather than one
category, so they stay in one column: Somers' |
effect |
Where the reported number comes from, once the model and the measure are fixed.
The contrast is a marker on the measure in the header, so the acronym stays the one thing
to look up: |
outcome_level |
Which level of the outcome to single out, as a named vector keyed by
outcome name —
|
trials |
Grouped-binomial (summed-score) outcomes only. The number of items behind the score,
fitting |
empirical |
Show the observed, unadjusted (crude) effect beside each modelled one —
the same quantity fitted with a single predictor, on exactly the same people. The distance
between the two is what adjustment changed, read left to right; it is the feature the package
exists for.
The two columns are the same column twice: same estimand, same colour ladder, one legend block.
Each cell prints the effect with the level it sits on — the observed percentage or mean on the
crude side, the adjusted prediction on the model side. A continuous predictor has no
levels, so its crude cell is the univariable slope, which assumes linearity: check that with
|
n |
How many people the table is about. |
color, color_signif
|
Colouring of the effect cells. What is left to choose is what each effect is compared to.
The two are mutually exclusive, and each always tests its own gap: a gap whose interval covers
zero is greyed whatever |
stars |
Logical (default |
ref |
The reference every effect is measured from — one argument, one meaning per kind
of predictor.
For a factor it is the level the others are compared against (a level name, or Anchoring a continuous predictor does not change its own effect — a slope is the same
wherever you start reading it from — but it does move the Constant row; its own row says
where the anchor sits,
For the level of the outcome, see |
multiplier |
How a continuous predictor's effect is scaled — the unit its row reports.
One unit is rarely a readable amount (a one-year change in The estimate, its interval and the observed companion all scale together; the p-value does not
move. Because the default is not 1, a continuous predictor's |
shape |
How a continuous predictor enters the model, when one straight line is not
enough. The
Example: |
stats |
The statistics shown in the model-summary footer (one block per model).
Model comparison happens by default wherever it means anything — when Three tests are asked for by name: |
conf_level |
Confidence level for the intervals. |
na |
Which rows each model is fitted on — the grain at which missing values are dropped.
|
display |
What each effect cell shows —
|
digits |
The number of decimals. A single integer sets every cell ( |
cleannames |
Logical. If |
subtext |
Optional character. A note shown below the table. |
caption |
A title for the table, stored on it and carried into every export. Without one a regression table titles itself from the model it shows. |
... |
One rarely-typed argument, plus internal plumbing.
Every argument removed or renamed while |
To learn what such a table says, read
Reading a
regression (vignette("tabxplor-reading-a-regression")); to look something up, the
regression vignette
(vignette("tabxplor-reg")).
New to regressions with tabxplor? A first model needs three arguments: data, outcome and
predictors. The model follows the outcome's type — a two-level factor gives logistic odds
ratios, a numeric a linear mean difference, a count Poisson ratios of means, a 3+ level
factor multinomial or ordinal odds ratios — so you rarely set family by hand.
The estimand is a cascade: family -> link -> measure -> effect, where "auto" means
follow from the left. family says what kind of number the outcome is; link which measure
the model estimates (a link is a measure, so it takes the same words); measure which one
is reported; effect where that number comes from. Set any one and everything to its right
re-derives, so most tables set none of them — and the one most people ever set is measure.
A coefficient exists only where the reported measure IS the model's own. Ask for another and
it is worked out from the model's predictions instead, averaged over the sample. So
measure = "ratio" on a binary outcome gives a marginal risk ratio from the logistic fit, while
link = "ratio" fits the modified Poisson and gives its conditional one — two different
quantities, and now two different arguments.
A tabxplor_grouped_tab (grouped by predictor), one effect column per model / outcome.
Beside the fit statistics the footer carries five model checks, each naming an assumption and
the instrument that measured it: Linearity and Proportionality (p-values) say whether the
estimate means what it claims, Dispersion whether the intervals are wide enough,
Influence whether one respondent carries the result, Collinearity why the intervals are
wide. Four are shown by default; stats = "linearity" adds the fifth, and shape is the cure
for what it flags. reg_check_plots() draws them all. What each one asks, and how to read it:
the regression
vignette.
tab_reg() covers linear, logistic, Poisson, multinomial and ordinal models, with survey designs.
Three families of models are deliberately not supported, and are unlikely to be: survival /
Cox models, mixed / multilevel models, and pooling over multiply-imputed datasets. Fit
those with their own packages.
A column header names the measure; the contrast is a marker on it —
no marker for a conditional effect, m for a marginal one, ref at the reference
profile — and measure = "log" wraps it (Model_mRR, Model_refRD,
Model_log(OR)). The observed companion carries the measure alone (Obs_RR).
OR — odds ratio (binomial, multinomial)
cumOR — cumulative odds ratio (ordinal)
RR — risk ratio (binomial, multinomial)
RD — risk difference (binomial, multinomial)
RoM — ratio of means (gaussian, poisson)
diff — mean difference (gaussian, poisson)
D — Somers' D (ordinal)
WR — win ratio (ordinal)
Clogg, C. C., Petkova, E. & Haritou, A. (1995). Statistical Methods for Comparing Regression
Coefficients between Models. American Journal of Sociology, 100(5), 1261-1293 — the
comparison color = "adjustment" implements.
Zou, G. (2004). A Modified Poisson Regression Approach to Prospective Studies with Binary Data.
American Journal of Epidemiology, 159(7), 702-706 — link = "ratio".
Altman, D. G. & Bland, J. M. (2003). Interaction revisited: the difference between two estimates.
BMJ, 326, 219 — the color = "between_groups" test.
reg_formulas() shows the formula each column was fitted with, and reg_measures()
what an outcome can be modelled as.
forest_plot() draws the finished table — every effect with its interval, its stars
and its colour, and (with empirical = TRUE) the observed effect beside it with the margin of
error of the gap. reg_check_plots() draws the model checks. tabxplor-display says what a
cell can show, tab() builds cross-tables.
# The shape table a continuous predictor draws under the footer is noise in an example: .opt <- options(tabxplor.shape_table = "no") # Logistic: the odds of being released, adjusted, beside the observed (crude) odds ratio. tab_reg(car_arrests, "released", c("colour", "checks")) # Linear: a mean difference in dollars. tab_reg(car_salaries, "salary", c("sex", "discipline", "rank")) # A count outcome: ratios of mean counts. tab_reg(car_arrests, "checks", c("colour", "employed"), family = "poisson") # `measure` reports another measure WITHOUT changing the model: a MARGINAL risk ratio, # averaged over the sample, still from the logistic fit. tab_reg(car_arrests, "released", c("colour", "checks"), measure = "ratio") # `link` changes the model: the CONDITIONAL risk ratio of a modified-Poisson fit. tab_reg(car_arrests, "released", c("colour", "checks"), link = "ratio") # A named list of predictor sets: one column per model, compared in the footer. tab_reg(car_salaries, "salary", list("sex alone" = "sex", "+ field" = c("sex", "discipline"), "+ rank" = c("sex", "discipline", "rank")), empirical = FALSE) # A continuous predictor cut into groups, on French survey data: tab_reg(questionr_hdv, "cinema", c("qualif", "age"), shape = c(age = "quartiles")) options(.opt)# The shape table a continuous predictor draws under the footer is noise in an example: .opt <- options(tabxplor.shape_table = "no") # Logistic: the odds of being released, adjusted, beside the observed (crude) odds ratio. tab_reg(car_arrests, "released", c("colour", "checks")) # Linear: a mean difference in dollars. tab_reg(car_salaries, "salary", c("sex", "discipline", "rank")) # A count outcome: ratios of mean counts. tab_reg(car_arrests, "checks", c("colour", "employed"), family = "poisson") # `measure` reports another measure WITHOUT changing the model: a MARGINAL risk ratio, # averaged over the sample, still from the logistic fit. tab_reg(car_arrests, "released", c("colour", "checks"), measure = "ratio") # `link` changes the model: the CONDITIONAL risk ratio of a modified-Poisson fit. tab_reg(car_arrests, "released", c("colour", "checks"), link = "ratio") # A named list of predictor sets: one column per model, compared in the footer. tab_reg(car_salaries, "salary", list("sex alone" = "sex", "+ field" = c("sex", "discipline"), "+ rank" = c("sex", "discipline", "rank")), empirical = FALSE) # A continuous predictor cut into groups, on French survey data: tab_reg(questionr_hdv, "cinema", c("qualif", "age"), shape = c(age = "quartiles")) options(.opt)
Turns each level of a tab_vars variable into a block of columns: fewer rows, more columns,
and every column stores which sub-population it belongs to (col_group) beside the variable it
shows (col_var). Every total row merges into ONE, named totname — the remaining tab_vars
are still index columns of their own, so the label does not repeat them. A total table's own
line joins that row when no tab_vars is left to hold it, and is dropped when one is.
tab()'s spread_vars calls it for you, and takes care of the totals beforehand.
tab_spread(tabs, spread_vars, names_prefix, names_sort = FALSE, totname = NULL)tab_spread(tabs, spread_vars, names_prefix, names_sort = FALSE, totname = NULL)
tabs |
|
spread_vars |
<tidy-select> The tab variables
to pass to column, with a syntax of type |
names_prefix |
String added to the start of every variable name. |
names_sort |
If no |
totname |
The name the merged total row takes, as a single string. |
A tibble of class tab, with less rows and more columns.
data <- forcats::gss_cat |> dplyr::filter(year %in% c(2000, 2014)) tabs <- tab(data, relig, marital, c(year, race), pct = "row", totaltab = "no", color = "difference", tot = "row", other_if_less_than = 30) tabs |> dplyr::select(year, race, relig, Married) |> tab_spread(race)data <- forcats::gss_cat |> dplyr::filter(year %in% c(2000, 2014)) tabs <- tab(data, relig, marital, c(year, race), pct = "row", totaltab = "no", color = "difference", tot = "row", other_if_less_than = 30) tabs |> dplyr::select(year, race, relig, Married) |> tab_spread(race)
What kind of object a tabxplor result is, read from its own declared model — the row-index
columns (their stored roles) and the table's stated kind — rather than guessed from column names.
tab_structure(x)tab_structure(x)
x |
A |
A named list:
container"table" or "list".
kind"crosstab" or "regression" (NA when the table carries no metadata).
mergedTRUE when several row variables are stacked in one table (a var column
names each row's variable).
groupedTRUE when the table has tab_vars (sub-tables).
row_vars, tab_vars, col_vars
the variables on each axis.
same_col_vars, same_tab_vars
for a list only: whether its tables agree.
tab_columns() for the column-axis view.
t <- tab(forcats::gss_cat, c(marital, relig), race, pct = "row") tab_structure(t)$mergedt <- tab(forcats::gss_cat, c(marital, relig), race, pct = "row") tab_structure(t)$merged
Turns a table's rows into its columns and its columns into its rows, and returns a real
tabxplor_tab — one you can keep piping through dplyr, colour, print and export.
Row percentages become column percentages, and the old total column and total row swap places.
Its job is the profile table: many variables down the page, a few groups across it. It is also
the only way to put a mean on a row, since a number given to row_vars is always cut into
levels — build the means as columns (tab(data, groups, numeric_vars)) and transpose.
Use the exporters' transpose = TRUE argument instead whenever you only need the OUTPUT:
it flips the finished render model after every colour and cell string is computed, so it handles
what a data-level flip cannot (several row variables, tab_vars sub-tables, columns of
unlike kinds).
tab(data, row_vars, col_vars, pct = "row") |> tab_kable(transpose = TRUE) # or tab_md() / tab_xl()
tab_transpose(tabs, name = NULL)tab_transpose(tabs, name = NULL)
tabs |
A single table made with |
name |
The name to give the new first (label) column, holding the old column-variable levels.
|
A transposed tabxplor_tab.
A transposed column stacks whatever the original rows held, so transposing a table that mixes
percentage and mean columns gives a mixed column. Its numbers and its cell layouts are exact;
only the colour ladder is shared, so an additive measure (color = "difference") grades
the percentage cells and leaves the others uncoloured, while a multiplicative one
(color = "ratio") grades them all — the percentage and mean ratio ladders being the same
rungs.
tab_spread, tab_compact, tab_export.
# race x marital, read as marital x race: tab(forcats::gss_cat, marital, race, pct = "row") |> tab_transpose() # the profile table: mean rows come from mean columns tab(forcats::gss_cat, marital, c(age, tvhours)) |> tab_transpose()# race x marital, read as marital x race: tab(forcats::gss_cat, marital, race, pct = "row") |> tab_transpose() # the profile table: mean rows come from mean columns tab(forcats::gss_cat, marital, c(age, tvhours)) |> tab_transpose()
Wrap column names and long labels
tab_wrap_text( tabs, wrap_rows = 35L, wrap_cols = 15L, exdent = 1, whitespace_only = TRUE, unbreakable_spaces = TRUE, brk = "\n" )tab_wrap_text( tabs, wrap_rows = 35L, wrap_cols = 15L, exdent = 1, whitespace_only = TRUE, unbreakable_spaces = TRUE, brk = "\n" )
tabs |
A |
wrap_rows |
Row labels are wrapped past this width (35 by default), as prose — on whitespace. |
wrap_cols |
Column NAMES are wrapped past this width (15 by default). A name is a compound
word, not prose, so it breaks at the seams a name is built from ( |
exdent |
On the second lines or more, the number or characters to use for indentation. |
whitespace_only |
Set to |
unbreakable_spaces |
Set to |
brk |
The string to use for linebreak : |
The same tabxplor_tab or tibble.
tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") |> tab_wrap_text(wrap_rows = 5L, wrap_cols = 8L)tab(forcats::gss_cat, race, marital, pct = "row", color = "difference") |> tab_wrap_text(wrap_rows = 5L, wrap_cols = 8L)
The Excel exporter behind tab_export: tab_export(x, format = "xl")
calls this. Colours follow the same palettes as the console and the HTML output, so a table looks
the same wherever it is read; change them with set_color_style and
set_color_breaks.
tab_xl( tabs, path = NULL, replace = FALSE, open = rlang::is_interactive(), lang = NULL, colnames_rotation = 0, remove_tab_vars = TRUE, colwidth = "auto", color_legend = TRUE, sheets = "auto", titles, caption = NULL, font_text = NULL, font_num = NULL, font_num_stars = NULL, text_size = 10, text_size_headers = 9, text_size_subtext = 9, theme = NULL, color = TRUE, transpose = FALSE, var_names = NULL, wrap_rows = 35, wrap_cols = 15, ratio_cells = NULL, check = FALSE, data = NULL, print_color_legend = lifecycle::deprecated(), ... )tab_xl( tabs, path = NULL, replace = FALSE, open = rlang::is_interactive(), lang = NULL, colnames_rotation = 0, remove_tab_vars = TRUE, colwidth = "auto", color_legend = TRUE, sheets = "auto", titles, caption = NULL, font_text = NULL, font_num = NULL, font_num_stars = NULL, text_size = 10, text_size_headers = 9, text_size_subtext = 9, theme = NULL, color = TRUE, transpose = FALSE, var_names = NULL, wrap_rows = 35, wrap_cols = 15, ratio_cells = NULL, check = FALSE, data = NULL, print_color_legend = lifecycle::deprecated(), ... )
tabs |
A table made with |
path, replace, open
|
The name, and possibly the path, of the Excel file to create (the
|
lang |
Colour-legend language: |
colnames_rotation |
Rotate the names of columns to an angle (in degrees). |
remove_tab_vars |
By default, |
colwidth |
Column widths. |
color_legend |
Print the colour legend below the table (with the subtext). |
sheets |
The Excel sheets options :
|
titles |
The titles of the different tables, as a character vector. When missing titles are given based on the names of the variables. |
caption |
A single caption; a shortcut that fills |
font_text, font_num, font_num_stars
|
Fonts for text (labels, headers) and for numbers. The
number font is chosen per table: |
text_size, text_size_headers, text_size_subtext
|
Font sizes of text elements. |
theme |
By default ( |
color |
Set to |
transpose |
Set to |
var_names |
Which variable names to write beside the table: |
wrap_rows |
Row labels are wrapped past this width (35 characters by default). |
wrap_cols |
Column headers are wrapped past this width (15 characters by default), at the seams a
compound name is built from ( |
ratio_cells |
What a ratio / odds-ratio cell holds in the workbook. Excel cannot compute
inside a number format, so a cell storing |
check |
Model-check plots to draw under each |
data |
The data frame the models were fitted on. Only needed when |
print_color_legend |
|
... |
Retired arguments, accepted and ignored with a deprecation message since 2.0.0
( |
The table(s) with formatting and colors in an Excel file, as a side effect.
Invisibly returns tabs.
A ratio or odds-ratio cell holds its reading value: the fold, signed by its direction. The sign
IS the marker — negative means the cell reads ÷ (or 1/) — so one formula gives the raw
ratio back, with no macro and no add-in:
=IF(A2<0, -1/A2, A2) the ratio itself =ABS(A2) how many times, whichever way it goes
Sorting and filtering need neither: the stored value is monotone in the direction it is read, so
"at least twice as likely" is >2 and "at least twice as unlikely" is <-2. Use
ratio_cells = "raw" when the untransformed ratio matters more than the reading.
# openxlsx2 is Suggests-only and tab_xl() stops without it, so guard the example: \donttest{} # does NOT exempt it from R CMD check --as-cran, which CRAN also runs without Suggests. if (requireNamespace("openxlsx2", quietly = TRUE)) { forcats::gss_cat |> tab(marital, race, pct = "row", color = "difference") |> tab_xl() }# openxlsx2 is Suggests-only and tab_xl() stops without it, so guard the example: \donttest{} # does NOT exempt it from R CMD check --as-cran, which CRAN also runs without Suggests. if (requireNamespace("openxlsx2", quietly = TRUE)) { forcats::gss_cat |> tab(marital, race, pct = "row", color = "difference") |> tab_xl() }
as.matrix() gives the table's numbers as a plain numeric matrix; as.table() gives the same
matrix as a base table, its dimnames named after the row and column
variables. That is the shape base R and the packages built on it expect — a correspondence
analysis, chisq.test(), mosaicplot():
FactoMineR::CA(as.matrix(tab(forcats::gss_cat, race, marital)), graph = FALSE)
Only the DATA cells come across. The total row, the total columns and the display-time rows (the
base count, add_pct, the p-value and model-fit lines) are dropped, because a test or an analysis
run on a table's own margins is wrong; totals = TRUE keeps them. Each cell contributes the
number it shows, so a plain tab gives counts, a pct = "row" table proportions,
and a numeric column means.
## S3 method for class 'tabxplor_tab' as.matrix(x, totals = FALSE, ...) ## S3 method for class 'tabxplor_tab' as.table(x, totals = FALSE, ...)## S3 method for class 'tabxplor_tab' as.matrix(x, totals = FALSE, ...) ## S3 method for class 'tabxplor_tab' as.table(x, totals = FALSE, ...)
x |
A table made with |
totals |
Set to |
... |
Not used. |
A numeric matrix, or a base table.
as.matrix(tabxplor_tab): the table's numbers as a numeric matrix
as.table(tabxplor_tab): the same, as a base table with named dimnames
tabs <- tab(forcats::gss_cat, race, marital) as.matrix(tabs) as.table(tabs) # a row-percentage table gives proportions, not counts: as.matrix(tab(forcats::gss_cat, race, marital, pct = "row"))tabs <- tab(forcats::gss_cat, race, marital) as.matrix(tabs) as.table(tabs) # a row-percentage table gives proportions, not counts: as.matrix(tab(forcats::gss_cat, race, marital, pct = "row"))
Every function that builds a table takes a display argument, and set_display() changes it
afterwards. This page is its vocabulary: the fields a cell may show, and the named layouts that
arrange them.
Asking for a layout in the call computes what it prints: one naming a confidence interval or
a contribution to the chi-squared turns that on, so display = "base_ci" needs no ci = beside
it. Every other field is already stored in the cell (see fmt), so set_display() on a finished
table changes no number — it only says which of them is shown, and names the argument that
would have filled a field the table does not carry.
Three ways to ask, from the shortest:
a named layout: display = "est_ci", "base_ratio", "mean_sd".
a single field: display = "ci", "diff", "n".
a {} template of your own: "{est} ({base})", "{pct} [{n}]".
In a template, the primary field is the first one written outside brackets — so an aside
may come first, "({base}) {est}", without ceasing to be an aside. The primary carries the
significance stars, it is what Excel writes and what get_num() returns, and it is the part the
colours paint.
A field may carry its own precision, "{est:3} ({base:1})", which beats every default —
the only way to set an aside's decimals independently of the estimate's.
est and base are scale-relative: est is whatever the column estimates (a percentage, a
mean difference, an odds ratio) and base the level it sits on. That is what lets one layout
name mean the same thing on a tab() crosstab and on a tab_reg() regression table.
A field with nothing to show renders blank but keeps its width, so the column stays aligned; a field empty in the whole column is dropped, and a note says which argument would have filled it.
The fields a {} template may name, and display may name on their own.
pct — the percentage. Needs a factor col_var and percentages: pct = "row" / "col" / "all".
n — the count.
wn — the weighted count. Needs weights (wt =).
mean — the mean. Needs a numeric col_var.
est — the estimate, whatever this column estimates — an odds ratio, a risk difference, a coefficient, a percentage. The one token that means the same thing on every table.
base — the level the estimate sits on: the percentage, the mean or the count. On a plain percentage table it is the same number as est; beside a regression effect it is the adjusted prediction. Needs a column that has a level beside its estimate.
diff — the difference from the reference. Needs a ref to compare to and something to compare: pct = "row" / "col", or a numeric col_var.
ratio — the ratio to the reference (relative risk, or a ratio of means). Needs a ref to compare to and something to compare: pct = "row" / "col", or a numeric col_var.
ci — the confidence interval of whatever the column compares, as [low;high].
moe — the margin of error — the same interval as ci, written as the half-width +/-x around the estimate. Void where the column compares a RATIO: a ratio's interval is symmetric on the LOG scale, so it has no half-width.
or — the odds ratio. Needs a factor col_var and a percentage base: pct = "row" / "col".
odds — the odds — pct / (1 - pct), the quantity an odds ratio is a ratio of. Printed on the odds ratio's own ladder, so a cell below 1 reads its inverse ("1/2.60") unless options(tabxplor.ratio_print = "raw") asks for the plain number. Void where the percentage is 1 and the odds infinite. Needs a factor col_var and a percentage base: pct = "row" / "col".
ctr — the cell's contribution to the chi-squared. Needs a factor col_var.
var — the variance. Needs a numeric col_var.
sd — the standard deviation, in the variable's own unit. Needs a numeric col_var.
cv — the coefficient of variation — the standard deviation as a percentage of the mean. Needs a numeric col_var whose mean is positive.
resid — the adjusted standardized residual – whether the cell departs from independence. Derived from the p-value and the sign of ctr, so it is read-only. Needs a factor col_var.
obs — the OBSERVED (crude) effect a modelled one is compared to. tab_reg() tables only. Needs tab_reg(empirical = TRUE) (an observed effect to compare the model to).
coef — the estimate on the model's LINK scale — the coefficient a linear or log-link model fitted. The same number as est where the column is already additive, its logarithm where the column shows a ratio. Needs a tab_reg() column (a crosstab estimates no coefficient).
gap — how far adjustment moved the effect: the gap between the modelled estimate and its observed counterpart, on the estimate's own scale. What color = "adjustment" grades — readable in print and Excel, not only in an html tooltip. Needs tab_reg(empirical = TRUE) (an observed effect to compare the model to).
The named layouts display accepts. They are spelt with the scale-relative
{est} / {base} fields, so one name means the same thing on a crosstab
and on a tab_reg table:
"est" ({est}) — the estimate alone.
"est_ci" ({est} {ci}) — the estimate with its confidence interval.
"est_base" ({est} ({base})) — the estimate and, in parentheses, the level it sits on.
"est_base_once" ({est}) — the estimate alone — the level is stated once, by the observed column beside it.
"est_coef" ({est} ({coef})) — the estimate and, in parentheses, the model's own coefficient.
"base_est_mdiff" ({est} ({diff})) — the estimate and, in parentheses, the same comparison as a difference.
"base_est_mratio" ({est} ({ratio})) — the estimate and, in parentheses, the same comparison as a ratio.
"est_obs" (({obs}) {est}) — the estimate and, before it in parentheses, the observed (crude) effect it is compared to.
"base_est" (({base}) {est}) — the level, then the estimate — the mirror of est_base, which sets a crude and a modelled effect side by side.
"base" ({base}) — the level alone: the percentage, the mean or the count.
"base_ci" ({base} {ci}) — the level with its confidence interval.
"base_moe" ({base} {moe}) — the level with its margin of error.
"base_diff" ({base} ({diff})) — the level and, in parentheses, its difference to the reference.
"base_ratio" ({base} ({ratio})) — the level and, in parentheses, its ratio to the reference.
"base_or" ({base} ({or})) — the level and, in parentheses, its odds ratio.
"or_base" ({or} ({base})) — the odds ratio and, in parentheses, the percentage it rests on.
"mean_sd" ({mean} (σ{sd})) — the mean and, in parentheses, its standard deviation.
"mean_cv" ({mean} (cv {cv})) — the mean and, in parentheses, its coefficient of variation — the spread as a percentage of the mean, comparable between columns measured in different units (the default where every mean is positive).
set_display() and get_display() change or read it on a built table; tab() and
tab_reg() set it in the call; fmt describes every field a cell stores, and
tabxplor-options the session-wide defaults.
tabxplor reads its display, colour, statistics and export defaults from options(), all
prefixed tabxplor.. Set any of them for a session with options(), e.g.
options(tabxplor.stars = TRUE), or once at the top of a script or .Rmd. The defaults are
established when the package loads (.onLoad()); most also have a per-call argument on the
relevant function, which always wins over the option.
tabxplor.print"console" (default): the medium a table auto-prints in. "html" renders the tab_html() table (in the Viewer pane in RStudio/Positron, and as a real html table in rmarkdown/Quarto documents) — recommended when you work in an IDE with a Viewer; "kable" is an accepted synonym of it (the pre-2.0.0 name). "md" renders the tab_md() table, so a bare tab() comes out as markdown — on standard output in a script, and raw (not as a verbatim block) in a knitted document, which is what an exploration notebook knitted straight to .md wants. Both media call their exporter bare, so tabxplor.theme and tabxplor.tab_kable_css govern them exactly as they govern an explicit call: options(tabxplor.tab_kable_css = FALSE) is what stops each table carrying its own stylesheet. There is no "xl" and no "forest": one writes a file, the other is a chart — ask for those by name.
tabxplor.starsFALSE (default): whether cells show significance stars, and at which cut-offs. FALSE (no stars), TRUE (the default ladder c("*" = 0.05, "**" = 0.01, "***" = 0.001)), or a named numeric giving your own – names are the glyphs, values the p-value cut-offs, e.g. options(tabxplor.stars = c("*" = 0.05, "**" = 0.01)). Off for tab(), on for tab_reg(). The LADDER is a render-time reading of each cell's stored p-value, so it is this option alone — change it and every table already built shows the new glyphs. Per-call stars =.
tabxplor.ratio_print"inverse" (default): prints a multiplicative value below its reference as the inverse — an odds ratio of 0.37 as 1/2.67, a mean ratio of 0.42 as /2.4 — so "2.7 times less" reads as strongly as "2.7 times more", and the same in a bracket. "raw" prints the plain number (0.37), the convention of most journals.
tabxplor.n"range" (default): how many people a table says are behind its numbers. "range" puts the unweighted base beside the Total cell of a crosstab (100% (9 838)) and in the n column of a regression table, printed as min-max when the blocks rest on different populations — several column variables losing different NAs, or several models. "min" prints the smallest base only, "no" shows no count at all. It replaces the add_n argument, deprecated in 2.0.0. Per-call n =.
tabxplor.color_whole_cellFALSE (default): EXPERT. A cell that prints SEVERAL fields reads as one number with an aside — 1/1.63*** (31%) — so the cell's rendering grades the number and the aside is set slightly back from the table's own text, following the theme. That covers the colour and, under theme = "print", the typography (bold, italic, underline) alike. Set to TRUE to extend the primary's own rendering over the whole cell instead (the pre-2.0.0 look). There is nothing to choose beyond that: which grey an aside takes belongs to the theme's palette, not to a per-cell option — see set_color_palette(). Console, html and Markdown; Excel renders a cell as a whole either way.
tabxplor.var_names"both" (default): which variable names the exporters annotate: "both", "rows", "cols", "none". Per-call var_names =.
tabxplor.var_labelsFALSE (default): in exports (markdown / html / Excel / plot), show a variable's label (the haven/labelled label attribute, if it has one) instead of its name. Display only – the table structure keeps canonical names, so name-based select() and references still work; the console always shows names.
tabxplor.cleannamesFALSE (default): clean up variable/level names in output. Also strips a "1-"-style prefix from labelled value labels turned into factor levels. Per-call cleannames =.
tabxplor.total_namesc(row = "Total", col = "Total", tab = "Ensemble", other = "Others") (default): the four synthetic labels a table carries: row and col name the total row and the total column, tab the total table (the one made when there are tab_vars), and other the level other_if_less_than lumps small levels into. A partial vector is allowed – options(tabxplor.total_names = c(tab = "Ensemble", other = "Autres")) leaves the first two alone. It replaces the total_names / totaltab_name / other_level arguments, deprecated in 2.0.0.
tabxplor.shape_auto_max12L (default): where shape = "auto" draws the line for a numeric row or tab variable: a column with at most this many distinct whole values is a counted number or a short scale, and keeps one level per value; anything else is continuous and is cut into "sd_bands". Raise it for a long scale, lower it to band more eagerly — or name the variable in shape and decide yourself.
tabxplor.color_breaksthe colour-break scales (a named list of pct_diff, pct_ratio, odds_ratio, mean_diff, mean_ratio, contrib, zscore, adj_ratio, adj_diff, adj_diff_std). Set with set_color_breaks(). Per-call color_breaks =.
tabxplor.color_style_theme (alias tabxplor.console_theme)the console palette theme, "light" or "dark"; set by set_color_palette() (which auto-detects the editor theme on load). NOT the export theme (tabxplor.theme / tabxplor.export_theme).
tabxplor.console_boldwhether to embolden the reference / total (and coloured) cells in the console, TRUE or FALSE. Auto-detected at load: TRUE in Positron and VS Code (which render ANSI bold at a fixed glyph width), FALSE in RStudio and unknown consoles (there bold is drawn wider and would break column alignment). Override it for your own front-end / font.
tabxplor.theme (alias tabxplor.export_theme)"light" (default): the export theme: "light", "dark", "auto" (follow the reader), or a black-and-white publication palette – "print_ready" picks one per table (marks for a cross-table, the emphasis ladder for a regression), or name it yourself: "print_marks", "print_emphasis", "print_minimalistic" ("bw" is a synonym of the last). See tab_css() for what each says. "auto" needs a stylesheet, so only tab_html(), tab_md() and tab_css() honour it; static backends resolve it to "light". A publication palette reaches every backend, Excel included. Per-call theme =.
tabxplor.print_rulesTRUE (default): every stylesheet tab_css() emits also carries a black-and-white publication palette inside an @media print block, so a table rendered in colour prints (or saves to PDF) publication-ready with no further action. Set FALSE if your printer is a colour one and the colours are the point, or name a palette ("print_emphasis") to print in that one instead of the default "print_minimalistic". "print_marks" and "print_ready" cannot be used here: their marks are cell text, and a print rule can restyle a page but not add characters to it. Per-call print_rules =.
tabxplor.background"page" (default): what a rendered table paints behind itself. "page" leaves it transparent, so the table sits on the page's own ground, whatever that is; "theme" paints the theme's own background, a card of its own; or name any CSS colour. Change it only where the page is not yours to follow — a dark table dropped into a light document, an html email. The interactive Viewer page paints itself either way, and a publication palette is always a sheet of white paper.
tabxplor.anova"welch" (default): which one-way ANOVA F is shown for mean columns: "welch" (robust) or "classic" (pooled variance). Both are always stored in the test attribute. Per-call anova =.
tabxplor.design_effectFALSE (default): a weighted tab() estimates the population but bases every interval and test on the raw number of respondents, so they carry no design effect — and the table's footer says so. Set TRUE and the same intervals account for the unequal weighting, exactly: a weight column IS a survey design (the flat one, ids = ~1), whose variance has a closed form in the per-cell sum(w^2) the aggregate already computes, so the base becomes n_eff = p(1-p) / Var_design(p) in every weighted descriptive confidence interval — factor proportions and means (cell, difference, ratio and the color = "odds_ratio" significance) — and the whole-table tests (test = TRUE) become survey::svychisq / a svyglm Wald F on that flat design. It reproduces survey to the last digit, Kish's (sum w)^2 / sum(w^2) being that same formula with each cell's own sum(w^2) discarded. Being exact rather than a bound, it can make an interval narrower as well as wider. It is blind to clustering and to calibration, which the weights do not record — and those are not symmetric: missing the calibration and the strata costs a few percent, in the safe direction, while missing the clusters of a face-to-face household survey can leave an interval several times too short (see the Weights section of vignette("tabxplor")). It needs the microdata weights, so tab_counts() on pre-aggregated counts cannot apply it (such a table states the raw basis in its footer rather than claiming a correction it does not have). Scope: tab() and its leaves only. tab_reg() never reads it — its crude empirical = companions are always on the weighted basis, beside a model column (survey::svyglm) that always was. For the full design effect — strata, clusters, fpc, calibration — pass a survey::svydesign as data; the option is then not consulted at all. Per-call design_effect =.
tabxplor.conf_level0.95 (default): confidence level for the intervals and significance tests. Since 2.0.0 each column records the level it was built at, so the colour thresholds follow the argument and this option is the fallback for a column that never recorded one (a hand-built fmt(), or a table from an older session). Per-call conf_level =.
tabxplor.legend_style"prose" (default): the colour-legend style in exports (tab_md(), tab_html(), tab_xl()): "prose" (full sentences) or "terse" (the compact one-line form the console uses). The console itself is always terse.
tabxplor.subtext_bold_labelTRUE (default): whether a note line opening on a short label and a colon ("Champ : adults", "Source: GSS") has that label set in bold, in every medium. FALSE prints the note as written. The label is at most four words, with no digit, so a free sentence is left alone.
tabxplor.test_lines"summary" (default): how many crosstab test rows the exporters (tab_md(), tab_html(), tab_xl()) append: "summary" (p-value + effect size), "all" (+ the raw statistic), "stat" (p-value + statistic), or "pvalue" (the single p-value row). The p-value row name states the test used ("pvalue (Chi2, Welch F; survey-design)") and the effect-size row its measure ("Cramer's V, eta2"). N is never added – it is already shown by the n column. The console block always shows N + p-value + effect size.
tabxplor.shape_table (alias tabxplor.spark)"all" (default): in a tab_reg() table, each continuous predictor's OBSERVED SHAPE — the outcome binned against the predictor, on the model's scale, with no model in it — drawn as a small curve in a shape table below the footer, beside the range it is a picture of (13-57% (OR 8.7)). It is the eye-half of the Linearity footer row, and the free one: no fit is involved. With tab_vars, one curve per group; with several outcomes, one per outcome. "all" draws it in every medium; "console" only where you are working, so exported tables stay unchanged; "no" never. TRUE / FALSE are accepted for the first and the last. The curve is drawn TO SCALE on the predictor as the model sees it, so a shape transform visibly straightens it when it is the right cure, and every predictor's curve is the same width. Its vertical window is floored by the data's own sampling noise, so a curve smaller than that is greyed and marked ns — read it as a flat line whatever its shape. In HTML the glyphs become an inline SVG; a plot never draws them (no graphics-device font has them). An ordinal or multinomial outcome has one curve per cut or per category and this draws only the first: reg_check_plots() shows them all.
tab_html() exporttabxplor.tab_kable_css (alias tabxplor.kable_css)TRUE (default): inline the stylesheet with each tab_html() / tab_md() table (self-contained). Set FALSE in a many-table document that emits tab_css() once at the top. Per-call css =.
tabxplor.tab_kable_tooltipsTRUE (default): show the per-cell hover tooltips (counts, confidence intervals, differences...) in html tables. Set FALSE once per document when every table auto-prints and tooltips are unwanted. Per-call tooltips =.
tabxplor.kable_popoverFALSE (default): use click popovers instead of hover tooltips. Per-call popover =.
tabxplor.tab_kable_num_fontthe HTML/markdown number-font CSS stack. Monospace by default so figures stay column-aligned (set a proportional stack to revert).
tabxplor.output_kableFALSE (default): makes
tab() return an html table instead of a table: the value can no longer be piped, filtered or re-coloured. Use options(tabxplor.print = "html"), which renders the same html at print time and leaves the object a table. Still honoured, with one message per session.
tab_xl() exporttabxplor.xl_font_text"DejaVu Sans Condensed" (default): text (labels/headers) font. Per-call font_text =.
tabxplor.xl_font_num"DejaVu Sans" (default): number font without stars. xlsx records ONE name (no fallback list), so set a font installed where the workbook is opened. Per-call font_num =.
tabxplor.xl_font_num_stars"Cascadia Mono" (default): number font with stars (monospace, so stars align). Per-call font_num_stars =.
tabxplor.xl_ratio_cells"fold" (default): what a ratio / odds-ratio cell HOLDS in the workbook: "fold" (the default) the signed fold, so Excel prints what the console prints and the cell stays a number; "raw" the untransformed ratio; "text" the exact display string. Per-call ratio_cells =.
tabxplor.export_dirNULL (default): default directory for exported files (NULL = the working / typed path).
tabxplor.lang"auto" (default): the colour-legend language: "auto" (follows the R/OS locale), "en" or "fr". Per-call lang =.
tabxplor.parallelFALSE (default): build the independent units of one call on parallel CPU cores (needs the mirai package): the per-row_var tables of a tab(), the models / tab_vars groups / outcomes of a tab_reg(). The result is byte-identical to the serial one. FALSE (default) never dispatches. "auto" (or TRUE) takes half the cores this session may actually use, at least 2 and at most 4 — so 2 on a dual-core laptop, 2 on a 4-core machine, 4 on 8 cores or more. An integer takes that many verbatim. The count respects options(mc.cores), a container's CPU quota and an HPC allocation (it reads them through the parallelly package when installed), and never exceeds 2 under R CMD check. It stays OPT-IN because starting the pool BLOCKS for about a second, so the first parallel table of a session is always slower than the serial one; from the third it is ahead. It pays off for MANY evenly sized units against a small or medium data frame — 24 tables run about 2.8x faster on 4 workers — and is a loss for few units or multi-million-row data, where shipping the population to each worker eats the gain. Set it once at the top of a script: options(tabxplor.parallel = "auto"). A model comparison (stats = "compare_*") is always serial and says so when asked: it is a test BETWEEN the fits, so they are built together. For one call only, wrap it in withr::with_options(list(tabxplor.parallel = "auto"), ...). The pool persists for the session; release it with tab_parallel_stop().
tabxplor.parallel_min2L (default): the smallest UNIT count worth dispatching – row_vars for tab(), models for tab_reg() (fewer runs serially, since the setup would outweigh the gain).
In tabxplor 1.x a fmt column carried one type attribute, whose seven values conflated two
facts. Since 2.0.0 they are two attributes: get_scale() / set_scale() say what the column
estimates (a key into the declared scale table), and get_pct_type() / set_pct_type() say
which kind of percentage it holds. These two functions translate, so 1.x code keeps running;
they are defunct in tabxplor 2.1.0.
get_type() re-fuses what 2.0.0 split, so it is a reading aid rather than an accessor:
level_mean reads back "mean", level_n reads "n", a level percentage reads its own
pct_type, and every effect scale (a difference, a ratio, an odds ratio, a coefficient) reads
"coef" — distinctions 1.x could not make are lost on the way back.
set_type(x, type) get_type(x, ...)set_type(x, type) get_type(x, ...)
x |
A |
type |
One of |
... |
Used in methods to add arguments in the future. |
get_type() a character vector; set_type() a modified fmt vector.
set_type(): set the retired type attribute of a fmt vector
get_type(): get the retired type of fmt columns
get_scale(), set_scale(), get_pct_type(), set_pct_type(), fmt_attr().
x <- fmt(n = c(10, 20), pct = c(0.3, 0.7), scale = "level_pct", pct_type = "row") get_type(x)x <- fmt(n = c(10, 20), pct = c(0.3, 0.7), scale = "level_pct", pct_type = "row") get_type(x)