{tabstats} is a lightweight package for displaying data
in clean, formatted tables directly in the console. It is mainly
designed for developers who wants to display their outputs (preferably
in a data frame object), and to make the output readable at a glance,
configurable without boilerplate, and friendly to interactive
workflows.
The package provides four main functions:
| Function | Purpose |
|---|---|
table_default() |
General-purpose data frame table |
table_summary() |
Two-column key-value summary table |
corr_matrix() |
Correlation matrix display |
cross_table() |
Cross tabulation with optional percentages |
All functions share a common design philosophy:
style = list(...) argument that accepts either predefined
style strings (e.g. "blue_bold") or plain lambda functions
(e.g. \(x) cli::col_red(x)).align
argument that accepts a single string, a length-2 vector, or a named
list.center_table = TRUE, which automatically pads the output to
the middle of your terminal.Install the following package from CRAN:
Or install the development version from GitHub:
The main API of this package displays the data you wanted to display into a specific format
table_default()Data frames usually looks like this when displayed:
mpg cyl disp hp drat
Mazda RX4 21.0 6 160 110 3.90
Mazda RX4 Wag 21.0 6 160 110 3.90
Datsun 710 22.8 4 108 93 3.85
Hornet 4 Drive 21.4 6 258 110 3.08
Hornet Sportabout 18.7 8 360 175 3.15
With table_default(), the data frame is now displayed in
an APA-style format, with configurable formatting.
─────────────────────────────────
mpg cyl disp hp drat
─────────────────────────────────
21.000 6 160 110 3.900
21.000 6 160 110 3.900
22.800 4 108 93 3.850
21.400 6 258 110 3.080
18.700 8 360 175 3.150
─────────────────────────────────
table_summary()Another form of table_default(), except it is best
suitable for displaying summarized data, where it requires 2 columns
data frame. The simplest use case is a named summary of values, like
model diagnostics or descriptive statistics, where the 1st column is the
name of the parameter (statistic) while the 2nd column is the
estimate.
df = data.frame(
Statistic = c("N", "Mean", "SD", "Min", "Max"),
Value = c("100", "3.45", "1.20", "1.00", "6.00")
)
table_summary(
df,
title = "Descriptive Statistics",
header = TRUE
)
Descriptive Statistics
----------------------
Statistic Value
----------------------
N 100
Mean 3.45
SD 1.20
Min 1.00
Max 6.00
----------------------
The header means you still wanted to display the
column names from the original df data frame, otherwise, no
column names are present.
corr_matrix()A much complex but niche function to display the matrix, specifically
designed for correlation matrices. If the display is a
correlation matrix, typically the output of cor(), you can
directly pass it.
Correlation Matrix
────────────────────────────────────────────────
Variable mpg cyl disp hp
────────────────────────────────────────────────
mpg 1 -0.852 -0.848 -0.776
────────────────────────────────────────────────
cyl -0.852 1 0.902 0.832
────────────────────────────────────────────────
disp -0.848 0.902 1 0.791
────────────────────────────────────────────────
hp -0.776 0.832 0.791 1
────────────────────────────────────────────────
But, if the data you wanted to display is not a matrix, but on
another form, you’re going to have to configure it by building a custom
spec with new_corr_data() for full control over which
values to appear.
A wild example, assuming you want to display the output from
rstatix::cor_test():
cor_mat =
iris |>
rstatix::cor_test(Sepal.Width, Sepal.Length, Petal.Length) |>
dplyr::mutate(
var1,
var2,
cor = format(cor, digits = 2),
statistic = format(statistic, digits = 2),
conf_int = paste0(
"[",
format(conf.low, digits = 2),
", ",
format(conf.high, digits = 2),
"]"
),
.keep = "unused"
)
cor_mat |>
with({
corr_matrix(
new_corr_data(
var1 = var1,
var2 = var2,
corr = cor,
statistic = statistic,
pval = p,
conf_int = conf_int
),
title = "Pearson Correlation Matrix"
)
})
Pearson Correlation Matrix
──────────────────────────────────────────────────────────────────────
Variable Sepal.Width Sepal.Length Petal.Length
──────────────────────────────────────────────────────────────────────
Sepal.Width 1 -0.12 -0.43
-1.4e+00 -5.8e+00
0.152 4.51e-08
[-0.27, 0.044] [-0.55, -0.288]
──────────────────────────────────────────────────────────────────────
Sepal.Length -0.12 1 0.87
-1.4e+00 2.2e+01
0.152 1.04e-47
[-0.27, 0.044] [ 0.83, 0.906]
──────────────────────────────────────────────────────────────────────
Petal.Length -0.43 0.87 1
-5.8e+00 2.2e+01
4.51e-08 1.04e-47
[-0.55, -0.288] [ 0.83, 0.906]
──────────────────────────────────────────────────────────────────────
cross_table()Another nice function to display the matrices — contingency tables, to be exact. It has (almost) everything to display the contingency table, including the observed frequencies, expected values, and percentages side by side.
m = matrix(
c(10, 20, 30, 40),
nrow = 2,
dimnames = list(
c("A", "B"),
c("X", "Y")
)
)
cross_table(m, percentage = "all")
┌──────────────────────────────────┐
| Layout for Cont. Table |
├──────────────────────────────────┤
| < Freq > (< Expected Value >) |
| < % by total row > |
| < % by total column > |
| < % by grand total > |
└──────────────────────────────────┘
Cross Tabulation: x by y
─────────────────────────────────────
y
─────────────────────────────────────
x X Y TOTAL
─────────────────────────────────────
A 10 (12) 30 (28) 40
25% 75% 40%
33% 43%
10% 30%
B 20 (18) 40 (42) 60
33% 67% 60%
67% 57%
20% 40%
─────────────────────────────────────
TOTAL 30 70 100
30% 70%
─────────────────────────────────────
All table functions provides an API to style the table.
table_default() has 2 parameters:
style_colnames to style the column names you wanted to
design, and style_columns if you want to apply the style to
the entire column you choose to style. Use td_style() to
configure the style of the column you choose to style.
table_summary() has a style parameter
to configure the style of the specific column you wanted to design. Use
sm_style() to configure the style of the specific
column.
cross_table() has a style parameter to
configure the style of the data displayed by the function. Use
ct_style() to configure the style of the displayed
values.
corr_matrix() has a style parameter to
configure the style of the values you entered, typically from the
display argument using new_corr_data(). Use
cm_style() to configure those values you assigned into
new_corr_data() into the displayed table.
The quickest way to style output is with a named string:
table_summary(
df,
title = "Descriptive Statistics",
header = TRUE,
style = sm_style(
left_col = "blue_bold",
right_col = "green",
title = "bold",
sep = ": "
)
)
Descriptive Statistics
-----------------------
Statistic Value
-----------------------
N : 100
Mean : 3.45
SD : 1.20
Min : 1.00
Max : 6.00
-----------------------
For full control, pass a lambda instead — it receives the text as its argument:
table_summary(
df,
title = "Descriptive Statistics",
header = TRUE,
style = sm_style(
left_col = \(x) cli::col_red(cli::style_bold(x)),
right_col = \(x) cli::col_cyan(x),
title = "bold",
sep = ": "
)
)
Descriptive Statistics
-----------------------
Statistic Value
-----------------------
N : 100
Mean : 3.45
SD : 1.20
Min : 1.00
Max : 6.00
-----------------------
Supported named style strings:
| String | Effect |
|---|---|
"bold" |
Bold text |
"italic" |
Italic text |
"blue", "red", "green",
"yellow" |
Foreground colour |
"blue_bold" |
Colour + bold (combinable with _) |
"red_italic" |
Colour + italic |
More example: Imagine you want to apply for the p-value of the output
from rstatix::cor_test(), an earlier example. In
corr_matrix(), you can even conditionally format the
specified value from new_corr_data().
cor_mat |>
with({
corr_matrix(
new_corr_data(
var1 = var1,
var2 = var2,
corr = cor,
statistic = statistic,
pval = p,
conf_int = conf_int
),
title = "Pearson Correlation Matrix",
style = cm_style(
pval = function(x) {
x_num = as.numeric(x)
if (is.na(x_num) || x_num > 0.05) {
cli::style_italic(x)
} else if (x_num > 0.01) {
cli::col_red(x)
} else {
cli::style_bold("<0.001")
}
}
)
)
})
Pearson Correlation Matrix
──────────────────────────────────────────────────────────────────────
Variable Sepal.Width Sepal.Length Petal.Length
──────────────────────────────────────────────────────────────────────
Sepal.Width 1 -0.12 -0.43
-1.4e+00 -5.8e+00
0.152 <0.001
[-0.27, 0.044] [-0.55, -0.288]
──────────────────────────────────────────────────────────────────────
Sepal.Length -0.12 1 0.87
-1.4e+00 2.2e+01
0.152 <0.001
[-0.27, 0.044] [ 0.83, 0.906]
──────────────────────────────────────────────────────────────────────
Petal.Length -0.43 0.87 1
-5.8e+00 2.2e+01
<0.001 <0.001
[-0.55, -0.288] [ 0.83, 0.906]
──────────────────────────────────────────────────────────────────────