Skip to content

Commit

Permalink
refactor: replace difference/ratio arguments in adjusted_rmst() and a…
Browse files Browse the repository at this point in the history
…djusted_rmtl() with contrast argument
  • Loading branch information
RobinDenz1 committed Apr 3, 2024
1 parent adfeb1c commit 0f39f2a
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 112 deletions.
38 changes: 30 additions & 8 deletions R/adjusted_auc.r
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,21 @@ auc_ratio <- function(data, group_1, group_2, conf_int, conf_level) {
adjusted_rmst <- function(adjsurv, to, from=0, conf_int=FALSE,
conf_level=0.95, interpolation="steps",
difference=FALSE, ratio=FALSE,
group_1=NULL, group_2=NULL) {
contrast="none", group_1=NULL, group_2=NULL) {

check_inputs_adj_rmst(adjsurv=adjsurv, from=from, to=to, conf_int=conf_int,
difference=difference, ratio=ratio)
contrast=contrast)

# temporary deprecation error
if (difference) {
stop("The argument 'difference' has been deprecated",
" as of version 0.11.1. Instead of 'difference=TRUE' please use",
" contrast='diff'.")
} else if (ratio) {
stop("The argument 'ratio' has been deprecated",
" as of version 0.11.1. Instead of 'ratio=TRUE' please use",
" contrast='ratio'.")
}

# set to FALSE if it can't be done
if (conf_int & is.null(adjsurv$boot_adj)) {
Expand All @@ -212,10 +223,10 @@ adjusted_rmst <- function(adjsurv, to, from=0, conf_int=FALSE,
out <- area_under_curve(adj=adjsurv, to=to, from=from,
conf_int=conf_int, conf_level=conf_level,
interpolation=interpolation)
if (difference) {
if (contrast=="diff") {
out <- auc_difference(data=out, group_1=group_1, group_2=group_2,
conf_int=conf_int, conf_level=conf_level)
} else if (ratio) {
} else if (contrast=="ratio") {
out <- auc_ratio(data=out, group_1=group_1, group_2=group_2,
conf_int=conf_int, conf_level=conf_level)
} else if (conf_int) {
Expand All @@ -234,10 +245,21 @@ adjusted_rmst <- function(adjsurv, to, from=0, conf_int=FALSE,
adjusted_rmtl <- function(adj, to, from=0, conf_int=FALSE,
conf_level=0.95, interpolation="steps",
difference=FALSE, ratio=FALSE,
group_1=NULL, group_2=NULL) {
contrast="none", group_1=NULL, group_2=NULL) {

check_inputs_adj_rmtl(adj=adj, from=from, to=to, conf_int=conf_int,
difference=difference, ratio=ratio)
contrast=contrast)

# temporary deprecation error
if (difference) {
stop("The argument 'difference' has been deprecated",
" as of version 0.11.1. Instead of 'difference=TRUE' please use",
" contrast='diff'.")
} else if (ratio) {
stop("The argument 'ratio' has been deprecated",
" as of version 0.11.1. Instead of 'ratio=TRUE' please use",
" contrast='ratio'.")
}

# set to FALSE if it can't be done
if (conf_int & is.null(adj$boot_adj)) {
Expand Down Expand Up @@ -266,10 +288,10 @@ adjusted_rmtl <- function(adj, to, from=0, conf_int=FALSE,
}
}

if (difference) {
if (contrast=="diff") {
out <- auc_difference(data=out, group_1=group_1, group_2=group_2,
conf_int=conf_int, conf_level=conf_level)
} else if (ratio) {
} else if (contrast=="ratio") {
out <- auc_ratio(data=out, group_1=group_1, group_2=group_2,
conf_int=conf_int, conf_level=conf_level)
} else if (conf_int) {
Expand Down
23 changes: 8 additions & 15 deletions R/input_checks.r
Original file line number Diff line number Diff line change
Expand Up @@ -559,8 +559,7 @@ check_inputs_sim_fun <- function(n, lcovars, outcome_betas, surv_dist,
}

## for adjusted_rmst function
check_inputs_adj_rmst <- function(adjsurv, from, to, conf_int, difference,
ratio) {
check_inputs_adj_rmst <- function(adjsurv, from, to, conf_int, contrast) {

if ((!is.numeric(from) | !is.numeric(to)) &
length(from)==1 & length(to)>=1) {
Expand All @@ -574,6 +573,9 @@ check_inputs_adj_rmst <- function(adjsurv, from, to, conf_int, difference,
stop("'from' must be smaller than 'to'.")
} else if (!(is.logical(conf_int) & length(conf_int)==1)) {
stop("'conf_int' must be either TRUE or FALSE.")
} else if (!(length(contrast)==1 && is.character(contrast) &&
contrast %in% c("none", "diff", "ratio"))) {
stop("'contrast' must be one of c('none', 'diff', 'ratio').")
} else if (conf_int & is.null(adjsurv$boot_adj)) {
warning("Cannot use bootstrapped estimates because",
" they were not estimated.",
Expand All @@ -590,16 +592,10 @@ check_inputs_adj_rmst <- function(adjsurv, from, to, conf_int, difference,
" estimates. Consider using a finer times grid in",
" 'adjustedsurv' or 'adjustedcif'.", call.=FALSE)
}

if (difference & ratio) {
warning("Cannot calculate the difference and the ratio simultaneously.",
" Only the difference will be displayed. To obtain the ratio",
" instead, set difference=FALSE.")
}
}

## for adjusted_rmtl function
check_inputs_adj_rmtl <- function(adj, from, to, conf_int, difference, ratio) {
check_inputs_adj_rmtl <- function(adj, from, to, conf_int, contrast) {

if ((!is.numeric(from) | !is.numeric(to)) &
length(from)==1 & length(to)>=1) {
Expand All @@ -614,6 +610,9 @@ check_inputs_adj_rmtl <- function(adj, from, to, conf_int, difference, ratio) {
stop("'from' must be smaller than 'to'.")
} else if (!(is.logical(conf_int) & length(conf_int)==1)) {
stop("'conf_int' must be either TRUE or FALSE.")
} else if (!(length(contrast)==1 && is.character(contrast) &&
contrast %in% c("none", "diff", "ratio"))) {
stop("'contrast' must be one of c('none', 'diff', 'ratio').")
} else if (conf_int & is.null(adj$boot_adj)) {
warning("Cannot use bootstrapped estimates because",
" they were not estimated.",
Expand All @@ -633,12 +632,6 @@ check_inputs_adj_rmtl <- function(adj, from, to, conf_int, difference, ratio) {
" estimates. Consider using a finer times grid in",
" 'adjustedsurv'/'adjustedcif'.", call.=FALSE)
}

if (difference & ratio) {
warning("Cannot calculate the difference and the ratio simultaneously.",
" Only the difference will be displayed. To obtain the ratio",
" instead, set difference=FALSE.")
}
}

## for adjustedsurv_test
Expand Down
8 changes: 2 additions & 6 deletions R/plot_auc_curve.r
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,8 @@ plot_auc_diff <- function(adj, estimate, times=NULL, conf_int=FALSE,
}

if (type=="diff") {
difference <- TRUE
ratio <- FALSE
ref_value <- 0
} else if (type=="ratio") {
difference <- FALSE
ratio <- TRUE
ref_value <- 1
}

Expand All @@ -144,12 +140,12 @@ plot_auc_diff <- function(adj, estimate, times=NULL, conf_int=FALSE,
plotdata <- adjusted_rmst(adjsurv=adj, from=0, to=times, conf_int=conf_int,
conf_level=conf_level, group_1=group_1,
group_2=group_2, interpolation=interpolation,
ratio=ratio, difference=difference)
contrast=type)
} else if (estimate=="rmtl") {
plotdata <- adjusted_rmtl(adj=adj, from=0, to=times, conf_int=conf_int,
conf_level=conf_level, group_1=group_1,
group_2=group_2, interpolation=interpolation,
ratio=ratio, difference=difference)
contrast=type)
}
plotdata$se <- NULL

Expand Down
22 changes: 13 additions & 9 deletions man/adjusted_rmst.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ This function can be utilized to estimate the confounder-adjusted restricted mea
adjusted_rmst(adjsurv, to, from=0, conf_int=FALSE,
conf_level=0.95, interpolation="steps",
difference=FALSE, ratio=FALSE,
group_1=NULL, group_2=NULL)
contrast="none", group_1=NULL,
group_2=NULL)
}
\arguments{
\item{adjsurv}{
Expand All @@ -33,16 +34,19 @@ A number specifying the confidence level of the bootstrap confidence intervals.
Either \code{"steps"} (default) or \code{"linear"}. This parameter controls how interpolation is performed. If this argument is set to \code{"steps"}, the curves will be treated as step functions. If it is set to \code{"linear"}, the curves wil be treated as if there are straight lines between the point estimates instead. Points that lie between estimated points will be interpolated accordingly. Should usually be kept at \code{"steps"}. See Details.
}
\item{difference}{
Whether to estimate the difference between two adjusted restricted mean survival times instead. When \code{conf_int=TRUE} is also specified, this function will also return the standard error of the difference, the associated confidence interval and a p-value. The p-value is the result of a one-sample t-test where the null-hypothesis is that the difference is equal to 0. To specify which difference should be calculated, the \code{group_1} and \code{group_2} arguments can be used. By default, the difference between the first and second level in \code{variable} is computed.
DEPRECATED. Use \code{contrast="diff"} instead.
}
\item{ratio}{
Whether to estimate the ratio between two adjusted restricted mean survival times instead. When \code{conf_int=TRUE} is also specified, this function will also return the associated confidence interval and a p-value. The p-value is the result of a one-sample t-test where the null-hypothesis is that the ratio is equal to 1. To specify which ratio should be calculated, the \code{group_1} and \code{group_2} arguments can be used. By default, the ratio between the first and second level in \code{variable} is computed. The confidence interval and test-statistic is estimated using the Fieller method.
DEPRECATED. Use \code{contrast="ratio"} instead.
}
\item{contrast}{
A single character string, specifying which contrast should be estimated. Needs to be one of \code{"none"} (estimate no contrasts, just return the adjusted RMST, the default), \code{"diff"} (estimate the difference) or \code{"ratio"} (estimate the ratio). When \code{conf_int=TRUE} is also specified and bootstrapping was performed in the original \code{adjustedsurv} call, this function will also estimate the corresponding standard error, the confidence interval and a p-value testing whether the difference is equal to 0 (or the ratio is equal to 1). To specify which difference/ratio should be calculated, the \code{group_1} and \code{group_2} arguments can be used. By default, the difference/ratio between the first and second level in \code{variable} is computed.
}
\item{group_1}{
Optional argument to get a specific difference or ratio. This argument takes a single character string specifying one of the levels of the \code{variable} used in the original \code{adjustedsurv} or \code{adjustedcif} function call. This group will be subtracted from. For example if \code{group_1="A"} and \code{group_2="B"} and \code{difference=TRUE} the difference \code{A - B} will be used. If \code{NULL}, the order of the factor levels in the original \code{data} determines the order. Ignored if \code{difference=FALSE} and \code{ratio=FALSE}.
Optional argument to get a specific difference or ratio. This argument takes a single character string specifying one of the levels of the \code{variable} used in the original \code{adjustedsurv} or \code{adjustedcif} function call. This group will be subtracted from. For example if \code{group_1="A"} and \code{group_2="B"} and \code{contrast="diff"} the difference \code{A - B} will be used. If \code{NULL}, the order of the factor levels in the original \code{data} determines the order. Ignored if \code{contrast="none"}.
}
\item{group_2}{
Also a single character string specifying one of the levels of \code{variable}. This corresponds to the right side of the difference/ratio equation. See argument \code{group_2}. Ignored if \code{difference=FALSE} and \code{ratio=FALSE}.
Also a single character string specifying one of the levels of \code{variable}. This corresponds to the right side of the difference/ratio equation. See argument \code{group_2}. Ignored if \code{contrast="none"}.
}
}
\details{
Expand All @@ -54,7 +58,7 @@ It can be interpreted as the mean survival time of individuals in group \eqn{Z =

\strong{\emph{Confidence Intervals}}

If the \code{adjsurv} object was created with \code{bootstrap=TRUE} in the \code{\link{adjustedsurv}} function, bootstrap confidence intervals and standard errors for the RMSTs can be approximated by setting \code{conf_int} to \code{TRUE}. If bootstrap samples occur where the survival function is not estimated up to \code{to}, the bootstrap sample is discarded and not used in further calculations. Approximate variance calculations not relying on the bootstrap estimates are currently not implemented. When using \code{difference=TRUE} the standard error of the difference between the two RMST values is approximated by \eqn{SE_{group_1 - group_2} = \sqrt{SE_{group_1}^2 + SE_{group_2}^2}}. When using \code{ratio=TRUE} the confidence intervals are calculated using the approximate formula given by Fieller (1954), assuming that the values are independent.
If the \code{adjsurv} object was created with \code{bootstrap=TRUE} in the \code{\link{adjustedsurv}} function, bootstrap confidence intervals and standard errors for the RMSTs can be approximated by setting \code{conf_int} to \code{TRUE}. If bootstrap samples occur where the survival function is not estimated up to \code{to}, the bootstrap sample is discarded and not used in further calculations. Approximate variance calculations not relying on the bootstrap estimates are currently not implemented. When using \code{contrast="diff"} the standard error of the difference between the two RMST values is approximated by \eqn{SE_{group_1 - group_2} = \sqrt{SE_{group_1}^2 + SE_{group_2}^2}}. When using \code{contrast="ratio"} the confidence intervals are calculated using the approximate formula given by Fieller (1954), assuming that the values are independent.

\strong{\emph{More than Two Groups}}

Expand Down Expand Up @@ -82,7 +86,7 @@ Returns a \code{data.frame} containing the columns \code{to} (the supplied \code

If \code{conf_int=TRUE} was used it additionally contains the columns \code{se} (the standard error of the restricted mean survival time), \code{ci_lower} (lower limit of the confidence interval), \code{ci_upper} (upper limit of the confidence interval) and \code{n_boot} (the actual number of bootstrap estimates used).

If \code{difference=TRUE} was used, it instead returns a \code{data.frame} that contains the columns \code{to}, \code{diff} (the difference between the RMST values), \code{se} (the standard error of the difference), \code{ci_lower} (lower limit of the confidence interval), \code{ci_upper} (upper limit of the confidence interval) and \code{p_value} (the p-value of the one-sample t-test). The same results are presented when using \code{ratio=TRUE}, except that the \code{diff} column is named \code{ratio} and that there is no \code{se} column.
If \code{contrast="diff"} was used, it instead returns a \code{data.frame} that contains the columns \code{to}, \code{diff} (the difference between the RMST values), \code{se} (the standard error of the difference), \code{ci_lower} (lower limit of the confidence interval), \code{ci_upper} (upper limit of the confidence interval) and \code{p_value} (the p-value of the one-sample t-test). The same results are presented when using \code{contrast="ratio"}, except that the \code{diff} column is named \code{ratio} and that there is no \code{se} column.
}
\references{
Sarah C. Conner, Lisa M. Sullivan, Emelia J. Benjamin, Michael P. LaValley, Sandro Galea, and Ludovic Trinquart (2019). "Adjusted Restricted Mean Survival Times in Observational Studies". In: Statistics in Medicine 38, pp. 3832-3860
Expand Down Expand Up @@ -138,10 +142,10 @@ adjrmst <- adjusted_rmst(adjsurv, from=0, to=0.5, conf_int=TRUE,
# calculate difference between adjusted restricted mean survival times
# from 0 to 0.5 in the two groups
adjrmst <- adjusted_rmst(adjsurv, from=0, to=0.5, conf_int=FALSE,
difference=TRUE)
contrast="diff")

# calculate ratio between adjusted restricted mean survival times
# from 0 to 0.5 in the two groups
adjrmst <- adjusted_rmst(adjsurv, from=0, to=0.5, conf_int=FALSE,
ratio=TRUE)
contrast="ratio")
}
Loading

0 comments on commit 0f39f2a

Please sign in to comment.