| tablearn | R Documentation |
tablearn() analyzes performance across consecutive cases, procedures, or
observations. It keeps individual case-level data for statistical inference
while allowing visually stable rolling or block summaries for learning-curve
display. A right-aligned rolling window such as cases 1-5, 2-6, 3-7, ... is
particularly useful when the question is: "What is my current performance
based on the most recent N cases?"
tablearn(
outcome,
data = NULL,
order = NULL,
operator = NULL,
type = c("auto", "continuous", "binary", "count"),
event = NULL,
better = c("auto", "lower", "higher"),
window = 5L,
window_type = c("rolling", "block", "none", "cumulative"),
window_align = c("right", "center", "left"),
window_step = NULL,
window_complete = TRUE,
window_fun = c("auto", "mean", "median", "trimmed_mean", "proportion", "rate"),
window_trim = 0.1,
window_weight = c("equal", "linear", "exponential"),
window_decay = 0.85,
window_ci = TRUE,
ci_level = 0.95,
window_ci_method = c("auto", "t", "normal", "wilson", "exact"),
interval = c("ci", "sd", "iqr", "range", "none"),
ewma = FALSE,
ewma_lambda = 0.2,
ewma_init = c("first", "mean", "target"),
smooth = TRUE,
smooth_method = c("loess", "spline", "lm", "gam", "none"),
smooth_on = c("window", "raw", "ewma"),
smooth_span = 0.6,
smooth_df = NULL,
smooth_ci = TRUE,
breakpoint = TRUE,
break_on = c("raw", "window"),
break_min_n = 8L,
break_grid = NULL,
break_boot = 0L,
phase = TRUE,
phase_breaks = NULL,
phase_names = c("Learning", "Consolidation", "Proficiency"),
phase_method = c("auto", "combined", "manual", "breakpoint", "proficiency"),
proficiency = TRUE,
proficiency_method = c("auto", "combined", "target", "lccusum", "breakpoint", "manual"),
proficiency_case = NULL,
proficiency_case_rule = c("confirmed", "first_stable"),
target_hold = 3L,
target_tolerance = 0,
plateau = TRUE,
plateau_ratio = 0.25,
plateau_slope = NULL,
stability = TRUE,
stability_metric = c("auto", "sd", "iqr", "cv", "none"),
stability_window = NULL,
stability_ratio = 0.75,
cusum = FALSE,
target = NULL,
cusum_method = c("deviation", "llr"),
cusum_alt = NULL,
cusum_reset = FALSE,
cusum_limit = NULL,
lccusum = FALSE,
p_acceptable = NULL,
p_unacceptable = NULL,
alpha = 0.05,
beta = 0.1,
racusum = FALSE,
expected = NULL,
adjust = NULL,
racusum_or = 2,
racusum_limit = NULL,
sensitivity = FALSE,
window_sensitivity = NULL,
plot = TRUE,
plot_type = c("auto", "learning", "cusum", "both"),
x_axis = c("case", "order"),
operator_display = c("facet", "overlay"),
show_raw = TRUE,
show_window = TRUE,
show_smooth = TRUE,
show_ewma = TRUE,
show_interval = TRUE,
show_break = TRUE,
show_proficiency = TRUE,
show_phase = TRUE,
show_target = TRUE,
show_current = TRUE,
title = NULL,
subtitle = NULL,
caption = NULL,
xlab = NULL,
ylab = NULL,
theme = c("publication", "minimal", "classic", "bw", "gray"),
legend = "bottom",
plot_opts = NULL,
lang = c("en", "vi"),
digit = 2,
p_digit = 3,
interpretation = FALSE,
viewer_plot_format = c("png", "svg"),
console = FALSE,
show = TRUE
)
outcome |
Outcome variable. May be a bare variable name, character name,
or |
data |
Data frame. If |
order |
Optional ordering variable such as case number or procedure date. If omitted, current row order is used. Data are sorted by this variable within each operator. |
operator |
Optional operator/surgeon/trainee variable. Curves and analyses are then calculated separately within operator. |
type |
Outcome type: |
event |
Event level for a binary outcome. If omitted, the second factor
level, |
better |
Direction of better performance: |
window |
Number of cases in a rolling or block window. Default 5. |
window_type |
|
window_align |
Alignment for rolling windows: |
window_step |
Number of cases to advance each window. Default is 1 for
rolling/cumulative and |
window_complete |
If |
window_fun |
|
window_trim |
Trim proportion used by |
window_weight |
|
window_decay |
Decay in |
window_ci |
Show point-wise interval for each window. |
ci_level |
Confidence level, default 0.95. |
window_ci_method |
|
interval |
Window interval displayed/calculated: |
ewma |
Logical; calculate an exponentially weighted moving average. |
ewma_lambda |
EWMA smoothing parameter in |
ewma_init |
EWMA starting value: |
smooth |
Logical; add a fitted smooth trend. |
smooth_method |
|
smooth_on |
Data used only for the descriptive smooth: |
smooth_span |
LOESS span. |
smooth_df |
Optional degrees of freedom for smoothing spline. |
smooth_ci |
Show a point-wise confidence band where the smoothing method supports one. |
breakpoint |
Logical; estimate a one-change-point piecewise regression. |
break_on |
|
break_min_n |
Minimum observations required on each side of a candidate breakpoint. |
break_grid |
Optional numeric vector of candidate case positions. |
break_boot |
Number of bootstrap replications for an exploratory percentile
CI for the breakpoint. |
phase |
Logical; create a phase summary table using the estimated or user supplied phase breaks. |
phase_breaks |
Optional numeric vector of manual phase boundaries. This is useful for 3+ named phases; automatic estimation currently provides one main change point. |
phase_names |
Names of phases. Defaults include Learning, Consolidation,
and Proficiency. Manual names are used when |
phase_method |
Phase classification rule: |
proficiency |
Logical; assess whether proficiency has been reached. |
proficiency_method |
|
proficiency_case |
Manual case number used only with
|
proficiency_case_rule |
For sustained-target proficiency, report the first
qualifying window ( |
target_hold |
Number of consecutive window estimates that must satisfy
|
target_tolerance |
Non-negative tolerance around |
plateau |
Logical; assess whether the post-breakpoint slope is sufficiently small to be interpreted as an operational plateau. A breakpoint alone is not automatically called proficiency. |
plateau_ratio |
Relative plateau threshold when |
plateau_slope |
Optional absolute slope threshold overriding
|
stability |
Logical; assess whether performance variability has fallen. |
stability_metric |
|
stability_window |
Number of early and late raw cases used to compare variability. Default is at least the selected learning-curve window size. |
stability_ratio |
Late/early variability ratio required for stability. Default 0.75 means late variability must be at most 75% of early variability. |
cusum |
Logical; calculate a conventional CUSUM from individual cases. |
target |
Clinical/quality target for CUSUM, target/reference line, and optional EWMA initialization. |
cusum_method |
|
cusum_alt |
Alternative binary failure probability for LLR-CUSUM. |
cusum_reset |
If |
cusum_limit |
Optional decision limit. If omitted, CUSUM is descriptive. |
lccusum |
Logical; calculate a binary LC-CUSUM designed to signal evidence that an acceptable failure rate has been reached. |
p_acceptable |
Acceptable failure probability for LC-CUSUM. |
p_unacceptable |
Unacceptable failure probability for LC-CUSUM; must be
larger than |
alpha, beta |
Type-I and Type-II error probabilities used in the LC-CUSUM decision boundary formula. |
racusum |
Logical; calculate a binary risk-adjusted CUSUM using likelihood scores and individual expected risks. |
expected |
Optional expected-risk variable or numeric vector for RA-CUSUM. Supplying externally validated or pre-operative expected risks is preferable. |
adjust |
Optional covariates used to fit a logistic expected-risk model if
|
racusum_or |
Odds ratio representing deterioration to be detected. Must be greater than 1. |
racusum_limit |
Optional RA-CUSUM decision limit. |
sensitivity |
Logical; calculate window-size sensitivity summaries. |
window_sensitivity |
Numeric vector of window sizes. If omitted and
|
plot |
Logical; create figures. Standard figures and Viewer figures use
base R and therefore require no add-on package. When |
plot_type |
|
x_axis |
|
operator_display |
|
show_raw, show_window, show_smooth, show_ewma, show_interval, show_break, show_proficiency, show_phase, show_target, show_current |
High-level plot layer switches. |
title, subtitle, caption, xlab, ylab |
Plot labels. Defaults are generated from the outcome and selected language. |
theme |
Plot theme: |
legend |
Legend position: |
plot_opts |
Nested list for advanced plot customization. See the dedicated Plot options section below. Values supplied here override defaults. |
lang |
|
digit |
Number of decimals for ordinary estimates in Viewer tables. |
p_digit |
Number of decimals for p-values in Viewer tables. |
interpretation |
Logical; include a short interpretation section in the
Viewer/console report. Default is |
viewer_plot_format |
Self-contained Viewer image format: |
console |
Print a concise analysis summary to the console. Default |
show |
Open the complete HTML report in the RStudio Viewer (or browser) and
display requested figures in the Plot pane. Default |
An object of class r4vn_tablearn. For one outcome it contains at least
raw, window, ewma, smooth, breakpoint, proficiency,
proficiency_evidence, phases, phase_classification, current,
current_status, cusum, lccusum, racusum, sensitivity, plots,
settings, plot_options, tables, and interpretation. With show = TRUE,
the returned object also carries the generated self-contained Viewer HTML/file path.
Multiple outcomes return class r4vn_tablearn_multi containing one analysis
per outcome.
With window = 5, window_type = "rolling", window_align = "right", and
window_step = 1, the first displayed point summarizes cases 1-5, the next
summarizes 2-6, then 3-7, and so on. Therefore the point at case 100 represents
performance in the most recent five cases (96-100). A newly observed case 101
updates the curve to cases 97-101. This is different from non-overlapping block
summaries and from a cumulative mean.
Overlapping rolling windows share observations and are therefore correlated.
tablearn() can display rolling windows for a stable curve while fitting the
change-point model and CUSUM on the original case sequence. The recommended
default is break_on = "raw"; CUSUM, LC-CUSUM and RA-CUSUM always operate on
individual sequential cases in this implementation.
plot_opts is a nested list. Every field is optional. Main groups are:
raw: show, color, fill, shape, size, alpha, stroke.
window: show, geom ("line", "point", "point_line"), color,
fill, shape, size, alpha, line_color, line_width, line_type.
window_interval: show, geom ("ribbon" or "errorbar"), color,
fill, alpha, line_width, width.
smooth: show, color, fill, line_width, line_type, alpha,
ci_show, ci_alpha.
ewma: show, color, line_width, line_type, alpha.
breakpoint: show, color, line_width, line_type, alpha, label,
label_text, label_size, label_angle, label_hjust, label_vjust.
proficiency: independent proficiency-line controls: show, color,
line_width, line_type, alpha, label, label_text, label_size,
label_angle, label_hjust, label_vjust.
phase: show, fills, alpha, border_color, border_width, label,
label_size, label_position.
target: show, color, line_width, line_type, alpha, label,
label_text, label_size.
current: show, color, fill, shape, size, alpha, stroke,
label, label_text, label_size, hjust, vjust.
axes: x_limits, y_limits, x_breaks, y_breaks, x_expand,
y_expand, y_percent, percent_accuracy, x_reverse, y_reverse,
x_trans, y_trans, x_date_format, x_date_breaks, clip.
legend: show, position, title, direction.
facet: ncol, nrow, scales.
operator: colors, shapes, line_types; layout is selected by
the high-level operator_display argument.
cusum: CUSUM-figure controls including colors, line_types, line_width,
alpha, point controls, zero-line controls, decision-limit controls, signal
marker controls, title/subtitle/caption/axis labels, and CUSUM-specific axis
limits/breaks.
theme: name, base_size, base_family, grid_major, grid_minor,
panel_border, axis_line, plot_title_face, legend_key_size.
text: optional title/subtitle/caption/axis/legend text sizes.
margins: top, right, bottom, left in points.
panel: optional background/border customization.
annotation: show_n, show_window_label.
This layered design lets the raw observations remain visible while the rolling curve, uncertainty, fitted smooth, target, breakpoint, estimated proficiency, phases, and current performance are styled independently.
tablearn() deliberately distinguishes a statistical/descriptive change point
from proficiency. A change point indicates a change in the learning trajectory;
proficiency is estimated from one or more operational criteria. With the default
combined rule, a supplied clinical target must be sustained for target_hold
consecutive displayed windows, and an enabled LC-CUSUM must cross its competency
decision boundary. A post-change plateau and reduced variability strengthen the
evidence. If no target or LC-CUSUM is supplied, a clear plateau can provide a
limited, data-driven proficiency estimate. Manual proficiency is also supported.
Automatic phase classification uses these results rather than forcing every
dataset into three phases. When both an earlier learning change point and a later
proficiency case are found, phases are Learning -> Consolidation -> Proficiency.
If proficiency is not established, a post-change segment is labelled
Consolidation rather than Proficiency. phase_breaks always allows complete
manual control for study protocols with pre-specified phases.
The evidence label (Strong, Moderate, Limited) is an R4VN rule-based
summary of concordant criteria, not a confidence probability and not a substitute
for a clinically defined competency standard.
With show = TRUE (default), tablearn() opens one self-contained HTML report
containing the key publication-ready tables and every requested figure. The same
figures are also sent to the Plot pane. Standard analysis, HTML rendering, learning
curves, CUSUM, LC-CUSUM, and RA-CUSUM use only base/recommended R packages.
ggplot2 is optional: when already installed, an advanced ggplot object is retained
in $plots; when it is absent, plotting still works through the base-R fallback.
mgcv is needed only when the user explicitly selects smooth_method = "gam";
otherwise the default smoothing methods use base R.
# --------------------------------------------------------------------------
# Reproducible demonstration data used by the examples below
# --------------------------------------------------------------------------
set.seed(2026)
n <- 150
d <- data.frame(
case = 1:n,
date = as.Date("2025-01-01") + 0:(n - 1),
surgeon = rep(c("A", "B", "C"), each = n / 3),
complexity = rbinom(n, 1, 0.35),
age = round(rnorm(n, 58, 12), 1)
)
d$time <- 115 - 48 * (1 - exp(-d$case / 30)) +
9 * d$complexity + rnorm(n, 0, 9)
d$score <- 55 + 28 * (1 - exp(-d$case / 35)) + rnorm(n, 0, 5)
d$expected_risk <- plogis(-1.8 + 0.9 * d$complexity + 0.012 * (d$age - 58))
actual_risk <- plogis(qlogis(d$expected_risk) - 0.010 * d$case)
d$complication <- rbinom(n, 1, actual_risk)
d$errors <- rpois(n, pmax(0.15, 3.2 * exp(-d$case / 45)))
# The full catalogue is interactive so R CMD check stays fast.
if (interactive()) {
# 1. Simplest end-user command. In an interactive session this opens the
# complete Viewer report and sends the learning curve to the Plot pane.
if (interactive()) {
m1 <- tablearn(time, data = d, order = case)
}
# 2. Right-aligned rolling window: 1-5, 2-6, 3-7, ...
m2 <- tablearn(time, data = d, order = case, window = 5,
show = FALSE, plot = FALSE)
head(m2$tables$Window_performance)
m2$tables$Current_performance
# 3. Non-overlapping blocks: 1-10, 11-20, 21-30, ...
m3 <- tablearn(time, data = d, order = case, window = 10,
window_type = "block", show = FALSE, plot = FALSE)
head(m3$window[, c(".start", ".end", ".value")])
# 4. Cumulative learning curve: 1, 1-2, 1-3, ...
m4 <- tablearn(time, data = d, order = case,
window_type = "cumulative", show = FALSE, plot = FALSE)
# 5. Individual-case series without aggregation.
m5 <- tablearn(time, data = d, order = case,
window_type = "none", show = FALSE, plot = FALSE)
# 6. Median and IQR for a skewed continuous outcome.
m6 <- tablearn(time, data = d, order = case, window = 7,
window_fun = "median", interval = "iqr",
show = FALSE, plot = FALSE)
# 7. Give recent cases greater weight within the rolling window.
m7 <- tablearn(time, data = d, order = case, window = 10,
window_weight = "exponential", window_decay = 0.85,
show = FALSE, plot = FALSE)
# 8. Add EWMA to the ordinary rolling curve.
m8 <- tablearn(time, data = d, order = case, window = 10,
ewma = TRUE, ewma_lambda = 0.20,
show = FALSE, plot = FALSE)
tail(m8$ewma)
# 9. Automatic piecewise change point. Inference uses raw cases by default.
m9 <- tablearn(time, data = d, order = case, window = 5,
breakpoint = TRUE, break_on = "raw",
show = FALSE, plot = FALSE)
m9$tables$Change_point
# 10. Sustained clinical target: <= 70 for 3 consecutive windows.
m10 <- tablearn(time, data = d, order = case, window = 5,
better = "lower", target = 70, target_hold = 3,
proficiency_method = "target",
show = FALSE, plot = FALSE)
m10$tables$Proficiency
m10$tables$Proficiency_evidence
# 11. Report the first qualifying window rather than the confirmation window.
m11 <- tablearn(time, data = d, order = case, window = 5,
better = "lower", target = 70, target_hold = 3,
proficiency_method = "target",
proficiency_case_rule = "first_stable",
show = FALSE, plot = FALSE)
# 12. Manual proficiency and prespecified study phases.
m12 <- tablearn(time, data = d, order = case, window = 5,
proficiency_method = "manual", proficiency_case = 60,
phase_method = "manual", phase_breaks = c(25, 59),
phase_names = c("Learning", "Consolidation", "Proficiency"),
show = FALSE, plot = FALSE)
m12$tables$Phase_classification
# 13. Binary outcome. Numeric 0/1 is recognized automatically; event = 1 is
# explicit and makes the scientific meaning clear.
m13 <- tablearn(complication, data = d, order = case, event = 1,
better = "lower", window = 20,
window_ci_method = "wilson",
show = FALSE, plot = FALSE)
m13$tables$Current_performance
# 14. Count outcome.
m14 <- tablearn(errors, data = d, order = case, type = "count",
better = "lower", window = 10,
show = FALSE, plot = FALSE)
# 15. Higher values can represent better performance.
m15 <- tablearn(score, data = d, order = case, better = "higher",
target = 80, target_hold = 3,
show = FALSE, plot = FALSE)
# 16. Conventional deviation CUSUM for a continuous outcome.
m16 <- tablearn(time, data = d, order = case, target = 75,
better = "lower", cusum = TRUE,
plot_type = "auto", show = FALSE, plot = FALSE)
m16$tables$Sequential_monitoring
# 17. Binary likelihood-ratio CUSUM.
m17 <- tablearn(complication, data = d, order = case, event = 1,
better = "lower", target = 0.10,
cusum = TRUE, cusum_method = "llr", cusum_alt = 0.20,
show = FALSE, plot = FALSE)
# 18. LC-CUSUM: evidence that an acceptable failure rate has been reached.
m18 <- tablearn(complication, data = d, order = case, event = 1,
better = "lower", window = 20,
lccusum = TRUE, p_acceptable = 0.10,
p_unacceptable = 0.25,
proficiency_method = "lccusum",
show = FALSE, plot = FALSE)
m18$tables$Proficiency
# 19. RA-CUSUM with externally supplied case-specific expected risks.
m19 <- tablearn(complication, data = d, order = case, event = 1,
better = "lower", window = 20,
racusum = TRUE, expected = expected_risk,
racusum_or = 2,
show = FALSE, plot = FALSE)
# 20. RA-CUSUM can estimate expected risk from covariates using base glm().
# For prospective monitoring, an external/pre-specified risk model is preferred.
m20 <- suppressWarnings(tablearn(
complication, data = d, order = case, event = 1,
racusum = TRUE, adjust = vars(complexity, c.age), racusum_or = 2,
show = FALSE, plot = FALSE
))
# 21. Separate learning curves by operator/surgeon.
m21 <- tablearn(time, data = d, order = case, operator = surgeon,
window = 8, operator_display = "facet",
show = FALSE, plot = FALSE)
m21$tables$Current_performance
# 22. Overlay operators in the same graph.
m22 <- tablearn(time, data = d, order = case, operator = surgeon,
window = 8, operator_display = "overlay",
show = FALSE, plot = FALSE)
# 23. Window-size sensitivity analysis.
m23 <- tablearn(time, data = d, order = case, window = 5,
sensitivity = TRUE,
window_sensitivity = c(3, 5, 10, 20),
show = FALSE, plot = FALSE)
m23$tables$Window_sensitivity
# 24. Multiple outcomes in one command.
m24 <- tablearn(vars(time, complication), data = d, order = case,
event = 1, window = 10,
show = FALSE, plot = FALSE)
names(m24$outcomes)
# 25. Use procedure date on the x-axis instead of consecutive case number.
m25 <- tablearn(time, data = d, order = date, x_axis = "order",
window = 7, show = FALSE, plot = FALSE)
# 26. Interpretive prose is opt-in; default is FALSE.
m26 <- tablearn(time, data = d, order = case,
interpretation = TRUE, show = FALSE, plot = FALSE)
m26$interpretation
# 27. Vietnamese generated interpretation/labels.
m27 <- tablearn(time, data = d, order = case, lang = "vi",
interpretation = TRUE, show = FALSE, plot = FALSE)
# 28. Conservative auto-detection: a numeric variable with two values other
# than 0/1 remains continuous unless event/type explicitly says binary.
d2 <- data.frame(case = 1:20, value = c(rep(100, 10), rep(50, 10)))
m28 <- tablearn(value, data = d2, order = case,
show = FALSE, plot = FALSE)
m28$settings$type
# 29. All publication-ready tables are directly accessible.
names(m10$tables)
summary(m10)$tables
# 30. Plot methods work even when ggplot2 is not installed because tablearn()
# has a base-R plotting fallback. These also appear inside the Viewer report.
if (interactive()) {
plot(m10, type = "learning")
m30 <- tablearn(complication, data = d, order = case, event = 1,
lccusum = TRUE, p_acceptable = .10,
p_unacceptable = .25, plot_type = "both")
plot(m30, type = "cusum")
}
# 31. High-level publication styling. Advanced ggplot styling is used when
# ggplot2 is installed; the Viewer/base-R figure remains available otherwise.
if (interactive()) {
m31 <- tablearn(
time, data = d, order = case, window = 5, target = 70,
plot_opts = list(
raw = list(alpha = .15, size = 1.0),
window = list(color = "#1F5A94", line_width = 1.2),
smooth = list(color = "#B23A48", line_width = 1.4),
proficiency = list(color = "#00796B"),
phase = list(alpha = .08),
current = list(fill = "#FFD166"),
theme = list(base_size = 12, grid_minor = FALSE)
)
)
}
} # end full interactive example catalogue
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.