tsahr

Trial Sequential Analysis (TSA) for meta-analyses of hazard ratios, in R.

Standalone Java application

A standalone Java implementation of tsahr is available as tsahr-java, providing the same TSA methodology without requiring R.

Adapts the classical Wetterslev/Thorlund/Copenhagen Trial Unit TSA framework to time-to-event outcomes, in the spirit of Miladinovic et al. (2013). It's worth distinguishing what's established methodology versus what this package specifically contributes:

Established components (from the cited literature):

This package's specific implementation choices:

Installation

# install.packages("remotes")
# remotes::install_github("tarak-dhaouadi/tsahr")
install.packages("tsahr", repos = c('https://tarak-dhaouadi.r-universe.dev', 'https://cloud.r-project.org'))

You'll also need its dependencies if you don't already have them:

install.packages(c("metafor", "readxl", "ggplot2"))

Usage

library(tsahr)

# Try it on a bundled example dataset: 20 studies by default;
# tsahr_example_data("HR_meta_2") is the 40-study version
path <- tsahr_example_data()

res <- tsa_hr(
  data              = path,
  target_HR         = 0.80,   # pre-specified anticipated HR (recommended)
  alpha_two_sided   = 0.05,
  power             = 0.80,
  allocation_source = "data"  # or "manual" with allocation_p = ...
)

summary(res)   # full results table
plot(res)      # the TSA chart

The subtitle of the chart shows the model/design summary and, on a second line, the pooled random-effects HR with its 95% CI, the p-value, tau² and I². With boundary_route = "analysis", the position and size of the "Analysis-route endpoint ... reached" label can be set with endpoint_label_x, endpoint_label_y and endpoint_label_size.

Random-effects inference

By default (re_inference = "standard") the random-effects model uses the usual normal-theory inference. re_inference = "hksj" (alias "knha") switches to the Hartung-Knapp-Sidik-Jonkman adjustment, and re_inference = "Hksj_adhoc" to its ad hoc variant in which the variance multiplier is never below 1:

res <- tsa_hr(path, target_HR = 0.80, re_inference = "hksj")
plot(res)   # the caption names the inference option

The tau² estimator (method), DARIS and the boundaries are unaffected; the pooled CI/p-value and the cumulative Z-curve (shown as the normal-equivalent of the HKSJ t statistic) change. The HKSJ statistic is undefined at the first look (cumulative$Z is NA there, and no point is drawn), and early looks generally are unstable (very few degrees of freedom) -- tsa_hr() prints a note about this under verbose = TRUE; see ?tsa_hr.

Using your own data

data can be a data.frame or a path to an .xlsx file with one row per study and (at least) these columns:

Column Meaning
Study Unique study label
log_HR log(hazard ratio) for that study
Std_Error standard error of log_HR
Events_Treatment events in the treatment arm
N_treatment patients randomised to treatment
Events_controls events in the control arm
N_controls patients randomised to control

Rows should be in chronological (publication) order — TSA results are order-dependent. Either pre-sort your data yourself, or pass order_by = "<column name>" (e.g. a publication-year column) to have tsa_hr() sort it for you explicitly:

res <- tsa_hr(path, target_HR = 0.80, order_by = "Year")

Saving the plot / results

tsa_hr() does not write files itself; use standard R tools:

p <- plot(res)
ggplot2::ggsave("tsa_plot.png", p, width = 11, height = 7.5, dpi = 300)

write.csv(res$cumulative,    "tsa_cumulative_results.csv", row.names = FALSE)
write.csv(res$summary_table, "tsa_summary.csv",             row.names = FALSE)

Important caveats

References

Miladinovic B, Mhaskar R, Hozo I, Kumar A, Mahony H, Djulbegovic B. "Optimal information size in trial sequential analysis of time-to-event outcomes reveals potentially inconclusive results because of the risk of random error." J Clin Epidemiol. 2013;66(6):654-9.

Wetterslev J, Thorlund K, Brok J, Gluud C. "Estimating required information size by quantifying diversity in random-effects model meta-analyses." BMC Med Res Methodol. 2009;9:86.

Attribution and license

tsahr contains code ported from the R package RTSA (Anne Lyngholm Soerensen, Markus Harboe Olsen, Theis Lange and Christian Gluud), licensed GPL (>= 2): the C++ boundary engine (src/rtsa_core.h, src/rtsa_engine.cpp), its R orchestration (R/rtsa_engine.R) and the earlier R-only reconstruction of it (R/obf_boundaries.R). RTSA is the R version of Trial Sequential Analysis (TSA), originally developed as a stand-alone Java program by the Copenhagen Trial Unit; the RTSA manual is heavily inspired by the user manual for TSA by Kristian Thorlund, Janus Engstrøm, Jørn Wetterslev, Jesper Brok, Georgina Imberger and Christian Gluud. The original TSA software is available at https://ctu.dk/tools:

Copenhagen Trial Unit, Centre for Clinical Intervention Research, Department 3344, Rigshospitalet, DK-2100 Copenhagen Ø, Denmark. Tel. +45 3545 7171, Fax +45 3545 7101, E-mail: tsa@ctu.dk

Because of that, tsahr is licensed GPL (>= 2) (as of 0.2.7.22; earlier releases were labelled MIT). See inst/COPYRIGHTS for the file-by-file provenance. If you use tsahr for boundary computations please also cite RTSA and the TSA software.