as.data.frame() extracts the balance statistics computed by bal.tab() as a tidy data frame, one row per covariate, sample, and statistic. format() returns the balance table exactly as print.bal.tab() displays it, as a data frame of formatted strings, ready to be passed to a table-rendering function.
Together they are meant to remove the need to pick apart a bal.tab object by hand when reporting balance in a document.
Usage
# S3 method for class 'bal.tab'
as.data.frame(
x,
row.names = NULL,
optional = FALSE,
...,
var.names = NULL,
wide = FALSE
)
# S3 method for class 'bal.tab'
format(
x,
...,
var.names = NULL,
digits = max(3L, getOption("digits") - 3L),
component = "balance"
)Arguments
- x
a
bal.tabobject; the output of a call tobal.tab().- row.names, optional
ignored; present for consistency with the
as.data.frame()generic.- ...
arguments passed to
print.bal.tab()to control which statistics, samples, and covariates are included, e.g.stats,disp,un,imbalanced.only, ordisp.thresholds. The.alland.noneshorthands are accepted as they are byprint(). Arguments that were not computed in the original call tobal.tab()cannot be requested here, for the same reason they cannot be requested inprint().- var.names
an optional object providing alternate names for the variables, which will otherwise be returned as they are stored. Entries given here add to those given in the original call to
bal.tab()and replace any entry they name. Seedisplay-optionsfor how to specify it.- wide
logical; foras.data.frame(), whether to return the table in the layoutprint()uses, with one column per sample and statistic, rather than the default tidy layout. Default isFALSE.- digits
for
format(), the number of significant digits to display. Default is the same as forprint().- component
for
format(), which table to return:"balance"(the default) for the balance table, or"observations"for the sample size table.
Value
as.data.frame() returns a data frame with one row per covariate, sample, and statistic, and these columns:
variablethe covariate name, as it appears in the row names of the balance table.
typethe covariate type:
"Binary","Contin.", or"Distance".sample"Unadjusted", or the name of the set of weights.statthe name of the statistic, using the same names as
bal.tab()'sstatsargument (e.g.,"mean.diffs"), with"mean"and"sd"for the distribution summary statistics.groupfor
"mean"and"sd", the name of the treatment group the value describes, asbal.tab()names it: the two group names for a binary treatment, the level for a multi-category one,"Uncensored"or"Full"for a censoring indicator, and"All"for a continuous treatment, which has no groups, or for the full sample whenpairwise = FALSE.NAfor a statistic that contrasts two groups, which belongs to neither of them.estimatethe value of the statistic.
thresholdthe balance verdict, e.g.
"Balanced, <0.1", when a threshold was requested for that statistic;NAfor a row it does not cover, such as a mean.threshold.valuethe numeric threshold, on the same rows.
The two threshold columns are present only when a threshold is on display for at least one statistic; when none is, they would be empty throughout and are omitted. The rest of the columns are always present.
When the data are segmented – by cluster, imputation, treatment pair, time point, or subclass – one further column per level of segmentation identifies it. Segmentation is always a column, never a nested list, so the result is a single rectangle whatever the shape of the input.
A multi-category treatment is reported one pair of groups at a time, but a mean or a standard deviation belongs to a group rather than to a comparison, and is the same in every pair that group appears in. Such a row therefore appears once, with pair set to NA; only the statistics that contrast two groups carry a pair. The same applies to the full sample's own means when pairwise = FALSE, which would otherwise be repeated against every group.
With wide = TRUE, the columns are those print() displays, with the covariate names moved from the row names into a variable column and any segmentation columns retained.
format() returns a data frame of character vectors with the covariate names as row names, formatted exactly as print() displays them: rounded to digits, padded to a common number of decimal places, with NA shown as ".".
Details
Both functions accept every argument print() accepts, and resolve them the same way, so the same warnings are raised when a requested value was not computed because quick = TRUE in the original call to bal.tab().
The variable column and the row names carry the covariates' display names, so var.names – given here or in the original call to bal.tab() – changes them. What the covariates are stored under is unaffected. See display-options.
as.data.frame() returns the balance statistics themselves, from each innermost balance table. It does not return the summaries across clusters, imputations, treatment pairs, or time points, which are aggregates of those statistics; format() returns the summary when that is what print() displays.
See also
love.plot()for a graphical alternativedisplay-optionsforvar.names
Examples
data("lalonde", package = "cobalt")
b <- bal.tab(treat ~ age + educ + race + re74, data = lalonde,
s.d.denom = "pooled", stats = c("m", "ks"),
thresholds = c(m = .1), un = TRUE)
#Tidy: one row per covariate, sample, and statistic
head(as.data.frame(b))
#> variable type sample stat group estimate
#> 1 age Contin. Unadjusted mean.diffs <NA> -0.24190362
#> 2 age Contin. Unadjusted ks.statistics <NA> 0.15772696
#> 3 educ Contin. Unadjusted mean.diffs <NA> 0.04475509
#> 4 educ Contin. Unadjusted ks.statistics <NA> 0.11137151
#> 5 race_black Binary Unadjusted mean.diffs <NA> 0.64044604
#> 6 race_black Binary Unadjusted ks.statistics <NA> 0.64044604
#> threshold threshold.value
#> 1 Not Balanced, >0.1 0.1
#> 2 <NA> NA
#> 3 Balanced, <0.1 0.1
#> 4 <NA> NA
#> 5 Not Balanced, >0.1 0.1
#> 6 <NA> NA
#The layout print() shows
as.data.frame(b, wide = TRUE)
#> variable Type Diff.Un M.Threshold.Un KS.Un
#> 1 age Contin. -0.24190362 Not Balanced, >0.1 0.15772696
#> 2 educ Contin. 0.04475509 Balanced, <0.1 0.11137151
#> 3 race_black Binary 0.64044604 Not Balanced, >0.1 0.64044604
#> 4 race_hispan Binary -0.08273168 Balanced, <0.1 0.08273168
#> 5 race_white Binary -0.55771436 Not Balanced, >0.1 0.55771436
#> 6 re74 Contin. -0.59575159 Not Balanced, >0.1 0.44703585
#Ready for knitr::kable() or any other table renderer
format(b)
#> Type Diff.Un M.Threshold.Un KS.Un
#> age Contin. -0.2419 Not Balanced, >0.1 0.1577
#> educ Contin. 0.0448 Balanced, <0.1 0.1114
#> race_black Binary 0.6404 Not Balanced, >0.1 0.6404
#> race_hispan Binary -0.0827 Balanced, <0.1 0.0827
#> race_white Binary -0.5577 Not Balanced, >0.1 0.5577
#> re74 Contin. -0.5958 Not Balanced, >0.1 0.4470
format(b, component = "observations")
#> Control Treated
#> All 429 185
#print()'s arguments work here too
as.data.frame(b, stats = "ks", un = FALSE)
#> variable type sample stat group estimate
#> 1 age Contin. Unadjusted ks.statistics <NA> 0.15772696
#> 2 educ Contin. Unadjusted ks.statistics <NA> 0.11137151
#> 3 race_black Binary Unadjusted ks.statistics <NA> 0.64044604
#> 4 race_hispan Binary Unadjusted ks.statistics <NA> 0.08273168
#> 5 race_white Binary Unadjusted ks.statistics <NA> 0.55771436
#> 6 re74 Contin. Unadjusted ks.statistics <NA> 0.44703585
