Skip to content

Commit

Permalink
Use argument formula instead of S3 generic
Browse files Browse the repository at this point in the history
Advantages:

* Less complex
* Able to use more informative arg names like `data` and `formula`
* Still easily pipe `data` as first arg even when using formula arg
  • Loading branch information
jdblischak committed Mar 18, 2024
1 parent 3ccb493 commit d38b2e9
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 80 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: simtrial
Type: Package
Title: Clinical Trial Simulation
Version: 0.3.2.12
Version: 0.3.2.13
Authors@R: c(
person("Keaven", "Anderson", email = "keaven_anderson@merck.com", role = c("aut")),
person("Yilong", "Zhang", email = "elong0527@gmail.com", role = c("aut")),
Expand Down
2 changes: 0 additions & 2 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# Generated by roxygen2: do not edit by hand

S3method(rmst,default)
S3method(rmst,formula)
export(counting_process)
export(create_cutting)
export(create_cutting_test)
Expand Down
75 changes: 29 additions & 46 deletions R/rmst.R
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@

#' RMST difference of 2 arms
#'
#' @param x Either a time-to-event dataset (see argument `data`) or a formula
#' that indicates the TTE, event, and group variables (in that exact order;
#' see Details below).
#' @param data A time-to-event dataset with a column `tte` indicating the
#' survival time and a column of `event` indicating whether it is
#' event or censor.
#' @param tau RMST analysis time.
#' @param var_label_tte Column name of the TTE variable.
#' @param var_label_event Column name of the event variable.
#' @param var_label_group Column name of the grouping variable.
#' @param formula (default: `NULL`) A formula that indicates the TTE, event, and
#' group variables (in that exact order; see Details below). This is an
#' alternative to specifying the variables as strings. If a formula is
#' provided, the values passed to `var_label_tte`, `var_label_event`, and
#' `var_label_group` are ignored.
#' @param reference A group label indicating the reference group.
#' @param alpha Type I error.
#' @param ... Currently unused (required for S3 generic function)
#'
#' @details
#' The formula interface is provided as a convenience to easily specify the TTE,
#' The argument `formula` is provided as a convenience to easily specify the TTE,
#' event, and grouping variables. Note however that only the order of the three
#' variables is actually used by the underlying function. Any functions applied
#' in the formula are ignored, and thus should only be used for documenting your
Expand All @@ -50,7 +51,7 @@
#' @examples
#' data(ex1_delayed_effect)
#' rmst(
#' x = ex1_delayed_effect,
#' data = ex1_delayed_effect,
#' var_label_tte = "month",
#' var_label_event = "evntd",
#' var_label_group = "trt",
Expand All @@ -62,47 +63,53 @@
#' library("survival")
#'
#' rmst(
#' Surv(month | evntd) ~ trt,
#' data = ex1_delayed_effect,
#' formula = Surv(month | evntd) ~ trt,
#' tau = 10,
#' reference = "0"
#' )
#'
#' # alternative
#' rmst(
#' ~ Surv(month, evntd, trt),
#' data = ex1_delayed_effect,
#' formula = ~ Surv(month, evntd, trt),
#' tau = 10,
#' reference = "0"
#' )
#'
#' # This example doesn't make statistical sense, but demonstrates that only the
#' # order of the 3 variables actually matters
#' rmst(
#' month ~ evntd + trt,
#' data = ex1_delayed_effect,
#' formula = month ~ evntd + trt,
#' tau = 10,
#' reference = "0"
#' )
rmst <- function(x, ...) {
UseMethod("rmst")
}

#' @rdname rmst
#' @export
rmst.default <- function(
x,
rmst <- function(
data,
tau = 10,
var_label_tte = "tte",
var_label_event = "event",
var_label_group = "treatment",
formula = NULL,
reference = "control",
alpha = 0.05,
...) {
alpha = 0.05) {
stopifnot(is.data.frame(data))

if (!is.null(formula)) {
variables <- colnames(stats::get_all_vars(formula = formula, data = data))
if (length(variables) != 3) {
stop("The formula interface requires exactly 3 variables specified")
}
var_label_tte <- variables[1]
var_label_event <- variables[2]
var_label_group <- variables[3]
}

res <- rmst_two_arm(
time_var = x[[var_label_tte]],
event_var = x[[var_label_event]],
group_var = x[[var_label_group]],
time_var = data[[var_label_tte]],
event_var = data[[var_label_event]],
group_var = data[[var_label_group]],
trunc_time = tau,
reference = reference,
alpha = alpha
Expand Down Expand Up @@ -348,27 +355,3 @@ rmst_single_arm <- function(

return(ans)
}

#' @rdname rmst
#' @export
rmst.formula <- function(x, data, tau = 10, reference = "control",
alpha = 0.05, ...) {
stopifnot(is.data.frame(data))

variables <- colnames(stats::get_all_vars(formula = x, data = data))
if (length(variables) != 3) {
stop("The formula interface requires exactly 3 variables specified")
}

ans <- rmst.default(
x = data,
tau = tau,
var_label_tte = variables[1],
var_label_event = variables[2],
var_label_group = variables[3],
reference = reference,
alpha = alpha
)

return(ans)
}
42 changes: 18 additions & 24 deletions man/rmst.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 29 additions & 7 deletions tests/testthat/test-unvalidated-rmst.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
test_that("rmst() snapshot test", {
data(ex1_delayed_effect)
data("ex1_delayed_effect")
observed <- rmst(
ex1_delayed_effect,
data = ex1_delayed_effect,
var_label_tte = "month",
var_label_event = "evntd",
var_label_group = "trt",
Expand All @@ -18,10 +18,10 @@ test_that("rmst() snapshot test", {
})

test_that("formula method matches default method", {
data(ex1_delayed_effect)
data("ex1_delayed_effect")

rmst_default <- rmst(
ex1_delayed_effect,
data = ex1_delayed_effect,
var_label_tte = "month",
var_label_event = "evntd",
var_label_group = "trt",
Expand All @@ -30,26 +30,48 @@ test_that("formula method matches default method", {
)

rmst_formula_1 <- rmst(
month ~ evntd + trt,
data = ex1_delayed_effect,
formula = month ~ evntd + trt,
tau = 10,
reference = "0"
)
expect_equal(rmst_formula_1, rmst_default)

rmst_formula_2 <- rmst(
survival::Surv(month | evntd) ~ trt,
data = ex1_delayed_effect,
formula = survival::Surv(month | evntd) ~ trt,
tau = 10,
reference = "0"
)
expect_equal(rmst_formula_2, rmst_default)

rmst_formula_3 <- rmst(
~ survival::Surv(month, evntd, trt),
data = ex1_delayed_effect,
formula = ~ survival::Surv(month, evntd, trt),
tau = 10,
reference = "0"
)
expect_equal(rmst_formula_3, rmst_default)
})

test_that("default and formula methods of rmst are pipeable", {
data("ex1_delayed_effect")

rmst_default <- ex1_delayed_effect |>
rmst(
var_label_tte = "month",
var_label_event = "evntd",
var_label_group = "trt",
tau = 10,
reference = "0"
)

rmst_formula_1 <- ex1_delayed_effect |>
rmst(
formula = month ~ evntd + trt,
tau = 10,
reference = "0"
)

expect_equal(rmst_formula_1, rmst_default)
})

0 comments on commit d38b2e9

Please sign in to comment.