diff --git a/.Rbuildignore b/.Rbuildignore index 97ae2bbf..b21033ab 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -20,3 +20,4 @@ images ^maicplus\.Rcheck$ ^maicplus.*\.tar\.gz$ ^maicplus.*\.tgz$ +^inst/dev/MAIC/MAIC-main/.Rbuildignore diff --git a/DESCRIPTION b/DESCRIPTION index d26a58c2..5f93a3e9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -6,21 +6,17 @@ Date: 2023-03-03 Authors@R: person("hta-pharma", , , "hta-pharma@example.com", role = c("aut", "cre")) Description: R package template with GitHub Actions workflows included. -License: Apache License 2.0 | file LICENSE +License: Apache License 2.0 URL: https://github.com/hta-pharma/maicplus/ BugReports: https://github.com/hta-pharma/maicplus/issues Depends: R (>= 3.6) Imports: - plumber, - shiny, - survival, - stringr + graphics, + stats, + survival Suggests: - future, - httr, knitr, - shinytest, testthat (>= 2.0) VignetteBuilder: knitr diff --git a/NAMESPACE b/NAMESPACE index 6ae92683..d19622db 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,2 +1,25 @@ # Generated by roxygen2: do not edit by hand +export(bucher) +export(center_ipd) +export(estimate_weights) +export(log_cum_haz_plot) +export(maic_tte_unanchor) +export(medSurv_makeup) +export(plot_weights) +export(process_agd) +export(process_ipd) +export(resid_plot) +export(survfit_makeup) +import(stats) +importFrom(graphics,abline) +importFrom(graphics,axis) +importFrom(graphics,hist) +importFrom(graphics,legend) +importFrom(graphics,lines) +importFrom(graphics,par) +importFrom(graphics,points) +importFrom(survival,Surv) +importFrom(survival,cox.zph) +importFrom(survival,coxph) +importFrom(survival,survfit) diff --git a/R/bucher.R b/R/bucher.R index 89c7447b..79388cca 100644 --- a/R/bucher.R +++ b/R/bucher.R @@ -4,33 +4,38 @@ #' Bucher method for adjusted treatment effect #' -#' Given two estimated treatment effects of A vs. C and B vs. C (i.e. two point estimates and corresponding standard errors), -#' derive the adjusted treatment of A vs. B using Bucher method, with two-sided confidence limits and Z-test p-value +#' Given two estimated treatment effects of A vs. C and B vs. C +#' (i.e. two point estimates and corresponding standard errors), +#' derive the adjusted treatment of A vs. B using Bucher method, +#' with two-sided confidence limits and Z-test p-value #' -#' @param trt a list with two named scalars for the study with interested experimental arm, one named 'est' for the point estimate, and the other named 'se' for the standard error +#' @param trt a list with two named scalars for the study with interested experimental arm, +#' one named `'est'` for the point estimate, and the other named `'se'` for the standard error #' @param com same as \code{trt}, but for the study with interested control arm -#' @param conf_lv a numerical scalar, prescribe confidence level to derive two-sided confidence interval for the adjusted treatment effect +#' @param conf_lv a numerical scalar, prescribe confidence level to derive two-sided +#' confidence interval for the adjusted treatment effect #' #' @return a list with 5 elements, #' \describe{ -#' \item est - a scalar, point estimate of the adjusted treatment effect -#' \item se - a scalar, standard error of the adjusted treatment effect (i.e. \code{est} in return) -#' \item ci_l - a scalor, lower confidence limit of a two-sided CI with prescribed nominal level by \code{conf_lv} -#' \item ci_u - a scalor, upper confidence limit of a two-sided CI with prescribed nominal level by \code{conf_lv} -#' \item pval - p-value of Z-test, with null hypothesis that \code{est} is zero +#' \item{est}{a scalar, point estimate of the adjusted treatment effect} +#' \item{se}{a scalar, standard error of the adjusted treatment effect (i.e. \code{est} in return)} +#' \item{ci_l}{a scalar, lower confidence limit of a two-sided CI with prescribed nominal level by \code{conf_lv}} +#' \item{ci_u}{a scalar, upper confidence limit of a two-sided CI with prescribed nominal level by \code{conf_lv}} +#' \item{pval}{p-value of Z-test, with null hypothesis that \code{est} is zero} #' } #' @export +#' @import stats #' #' @examples bucher <- function(trt, com, conf_lv = 0.95) { est <- trt$est - com$est se <- sqrt(trt$se^2 + com$se^2) - ci_l <- est - qnorm(0.5 + conf_lv / 2) * se - ci_u <- est + qnorm(0.5 + conf_lv / 2) * se + ci_l <- est - stats::qnorm(0.5 + conf_lv / 2) * se + ci_u <- est + stats::qnorm(0.5 + conf_lv / 2) * se if (est > 0) { - pval <- 2 * (1 - pnorm(est, 0, se)) + pval <- 2 * (1 - stats::pnorm(est, 0, se)) } else { - pval <- 2 * pnorm(est, 0, se) + pval <- 2 * stats::pnorm(est, 0, se) } list( @@ -44,13 +49,14 @@ bucher <- function(trt, com, conf_lv = 0.95) { # functions NOT to be exported --------------------------------------- -#' Report-friendly output format for resutl from Bucher's method +#' Report-friendly output format for result from Bucher's method #' #' @param output output from \code{\link{bucher}} function #' @param ci_digits an integer, number of decimal places for point estimate and derived confidence limits #' @param pval_digits an integer, number of decimal places to display Z-test p-value #' -#' @return a character vector of two elements, first element inf format of 'est (ci_l; ci_u)', second element is Z-test p-value, rounded according to \code{pval_digits} +#' @return a character vector of two elements, first element in format of 'est (ci_l; ci_u)'`, +#' second element is the Z-test p-value, rounded according to \code{pval_digits} print_bucher <- function(output, ci_digits = 2, pval_digits = 3) { res <- paste0( diff --git a/R/maic_unanchored_tte.R b/R/maic_unanchored_tte.R index c410f7c9..eb1a4ee6 100644 --- a/R/maic_unanchored_tte.R +++ b/R/maic_unanchored_tte.R @@ -2,7 +2,7 @@ #' #' @param useWt a numeric vector of individual MAIC weights, length should the same as \code{nrow(dat)} #' @param dat a data frame that meet format requirements in 'Details', individual patient data (IPD) of internal trial -#' @param dat_ext a data frame, pseudo IPD from digitalized KM curve of external trial +#' @param dat_ext a data frame, pseudo IPD from digitized KM curve of external trial #' @param trt a character string, name of the interested treatment in internal trial (real IPD) #' @param trt_ext character string, name of the interested comparator in external trial used to subset \code{dat_ext} (pseudo IPD) #' @param endpoint_name a character string, name of the endpoint @@ -13,11 +13,12 @@ #' \itemize{ #' \item treatment - character or factor column #' \item status - logical column, TRUE for censored/death, FALSE for otherwise -#' \time time - numeric column, observation time of the \code{status}; unit in days +#' \item time - numeric column, observation time of the \code{status}; unit in days #' } #' #' @return #' @importFrom survival Surv survfit coxph cox.zph +#' @importFrom graphics par axis lines points legend abline #' @export #' #' @examples @@ -50,10 +51,10 @@ maic_tte_unanchor <- function(useWt, dat, dat_ext, trt, trt_ext, # derive km w and w/o weights kmobj <- survfit(Surv(time, status) ~ treatment, dat, conf.type = "log-log") kmobj_adj <- survfit(Surv(time, status) ~ treatment, dat, weights = dat$weight, conf.type = "log-log") - + par(cex.main=0.85) - km_makeup(kmobj, kmobj_adj, time_scale = time_scale, - trt = trt, trt_ext = trt_ext, + km_makeup(kmobj, kmobj_adj, time_scale = time_scale, + trt = trt, trt_ext = trt_ext, endpoint_name = endpoint_name) res[["plot_km"]] <- grDevices::recordPlot() @@ -131,13 +132,14 @@ maic_tte_unanchor <- function(useWt, dat, dat_ext, trt, trt_ext, } #' helper function: sort out a nice report table to summarize survival analysis results -#' for maic_tte_unanchor +#' for `maic_tte_unanchor` #' #' @param coxobj returned object from \code{\link[survival]{coxph}} #' @param medSurvobj returned object from \code{\link{medSurv_makeup}} #' @param tag a string, by default NULL, if specified, an extra 1st column is created in the output #' -#' @return a data frame with sample size, incidence rate, median survival time with 95%CI, hazard ratio estimate with 95%CI and wald test of hazard ratio +#' @return a data frame with sample size, incidence rate, median survival time with 95% CI, hazard ratio estimate with +#' 95% CI and Wald test of hazard ratio report_table <- function(coxobj, medSurvobj, tag = NULL) { hr_res <- format(round(summary(coxobj)$conf.int[-2], 2), nsmall = 2) diff --git a/R/matching.R b/R/matching.R index 5ac89b43..fd116759 100644 --- a/R/matching.R +++ b/R/matching.R @@ -10,16 +10,18 @@ #' @param data a numeric matrix, centered covariates of IPD, no missing value in any cell is allowed #' @param centered_colnames a character or numeric vector (column indicators) of centered covariates #' @param startVal a scalar, the starting value for all coefficients of the propensity score regression -#' @param method a string, name of the optimization algorithm (see 'method' argument of \code{base::optim()}). The default is "BFGS", other options are "Nelder-Mead", "CG", "L-BFGS-B", "SANN", and "Brent" +#' @param method a string, name of the optimization algorithm (see 'method' argument of \code{base::optim()}). +#' The default is `"BFGS"`, other options are `"Nelder-Mead"`, `"CG"`, `"L-BFGS-B"`, `"SANN"`, and `"Brent"` #' @param ... all other arguments from \code{base::optim()} #' #' @return a list with the following 4 elements, #' \describe{ -#' \item data - a data.frame, includes the input \code{data} with appended column 'weights' and 'scaled_weights'. Scaled weights has a summation to be the number of rows in \code{data} that has no missing value in any of the effect modifiers -#' \item centered_colnames - column names of centered effect modifiers in \code{data} -#' \item nr_missing - number of rows in \code{data} that has at least 1 missing value in specified centered effect modifiers -#' \item ess - effective sample size, square of sum divided by sum of squares -#' \item opt - R object returned by \code{base::optim()}, for assess convergence and other details +#' \item{data}{a data.frame, includes the input \code{data} with appended column 'weights' and 'scaled_weights'. +#' Scaled weights has a summation to be the number of rows in \code{data} that has no missing value in any of the effect modifiers} +#' \item{centered.colnames}{column names of centered effect modifiers in \code{data}} +#' \item{nr_missing}{number of rows in \code{data} that has at least 1 missing value in specified centered effect modifiers} +#' \item{ess}{effective sample size, square of sum divided by sum of squares} +#' \item{opt}{R object returned by \code{base::optim()}, for assess convergence and other details} #' } #' @export #' @@ -105,6 +107,7 @@ estimate_weights <- function(data, centered_colnames = NULL, startVal = 0, metho #' @param main_title a character string, main title of the plot #' #' @return a plot of unscaled or scaled weights +#' @importFrom graphics hist #' @export plot_weights <- function(wt, main_title = "Unscaled Individual Weights") { diff --git a/R/process_data.R b/R/process_data.R index 04a5e969..76b7dd19 100644 --- a/R/process_data.R +++ b/R/process_data.R @@ -88,7 +88,8 @@ process_agd <- function(raw_agd) { with(use_agd, use_agd[tolower(ARM)=="total",,drop=FALSE]) } -#' Dummize categorical variables in an individual patient data (ipd) + +#' Create dummy variables from categorical variables in an individual patient data (ipd) #' #' This is a convenient function to convert categorical variables into dummy binary variables. #' This would be especially useful if the variable has more than two factors. @@ -173,9 +174,11 @@ center_ipd <- function(ipd, agd){ } + # Functions NOT to be exported --------------------------------------- -#' Calculate pooled arm statistics in AgD based on arm-specific statistics + +#' Calculate pooled arm statistics in Aggregated Data (AgD) based on arm-specific statistics #' #' This is a convenient function to pool arm statistics ## FILL IN #' @@ -194,8 +197,8 @@ complete_agd <- function(use_agd) { use_agd$ARM[rowId] <- "total" # complete N and count - NN <- use_agd$N[rowId] <- sum(use_agd$N, na.rm=TRUE) - nn <- use_agd$N[-rowId] + NN <- use_agd[["N"]][rowId] <- sum(use_agd[["N"]], na.rm=TRUE) + nn <- use_agd[["N"]][-rowId] for(i in grep("_COUNT$",names(use_agd),value=TRUE)){ use_agd[[i]][rowId] <- sum(use_agd[[i]], na.rm=TRUE) } @@ -207,7 +210,7 @@ complete_agd <- function(use_agd) { # complete SD for(i in grep("_SD$",names(use_agd),value=TRUE)){ - use_agd[[i]][rowId] <- sqrt( sum(use_agd[[i]]^2*(nn-1))/(N-1) ) + use_agd[[i]][rowId] <- sqrt( sum(use_agd[[i]]^2*(nn-1))/(NN-1) ) } # complete MEDIAN, approximately!! @@ -220,7 +223,6 @@ complete_agd <- function(use_agd) { } - #' helper function: transform TTE ADaM data to suitable input for survival R pkg #' #' @param dd data frame, ADTTE read via haven::read_sas diff --git a/R/survival-helper.R b/R/survival-helper.R index 60e7d053..8f22818d 100644 --- a/R/survival-helper.R +++ b/R/survival-helper.R @@ -1,4 +1,4 @@ -#' helper function: makeup to get median survival time from a survival::survfit object +#' helper function: makeup to get median survival time from a `survival::survfit` object #' #' extract and display median survival time with confidence interval #' @@ -6,7 +6,7 @@ #' @param legend a character string, name used in 'type' column in returned data frame #' @param time_scale a character string, 'year', 'month', 'week' or 'day', time unit of median survival time #' -#' @return a data frame with a index column 'type', mdian survival time and confidence interval +#' @return a data frame with a index column 'type', median survival time and confidence interval #' @export medSurv_makeup <- function(km_fit, legend = "before matching", time_scale) { timeUnit <- list("year" = 365.24, "month" = 30.4367, "week" = 7, "day" = 1) @@ -30,7 +30,7 @@ medSurv_makeup <- function(km_fit, legend = "before matching", time_scale) { -#' helper function: makeup survival::survfit object for km plot +#' helper function: makeup `survival::survfit` object for km plot #' #' @param km_fit returned object from \code{survival::survfit} #' @@ -210,9 +210,9 @@ log_cum_haz_plot <- function(clldat, time_scale, log_time = TRUE, endpoint_name } -#' Plot schoenfeld residual plot for a Cox model fit +#' Plot Schoenfeld residuals for a Cox model fit #' -#' @param coxobj object returned from \code{\link[surival]{coxph}} +#' @param coxobj object returned from \code{\link[survival]{coxph}} #' @param time_scale a character string, 'year', 'month', 'week' or 'day', time unit of median survival time #' @param log_time logical, TRUE (default) or FALSE #' @param endpoint_name a character string, name of the endpoint @@ -233,7 +233,7 @@ resid_plot <- function(coxobj, time_scale = "month", log_time = TRUE, endpoint_n cex = 0.9, col = "navyblue", yaxt = "n", ylab = "Unscaled Schoenfeld Residual", xlab = paste0(ifelse(log_time, "Log-", ""), "Time in ", time_scale), main = paste0( - "Diagnosis Plot: Unscaled Schoefeld Residual\nEndpoint: ", endpoint_name, + "Diagnosis Plot: Unscaled Schoenfeld Residual\nEndpoint: ", endpoint_name, ifelse(subtitle == "", "", "\n"), subtitle ) ) diff --git a/inst/WORDLIST b/inst/WORDLIST index 03096e3f..6b777200 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -10,3 +10,17 @@ initializer pre repo Forkers +comparator +Bucher +Bucher's +unadjusted +MAIC +ci +ESS +IPD +Schoenfeld +ADTTE +ADaM +unanchored +TTE +AgD diff --git a/inst/dev/maicplus/maicplus-main/bucher.R b/inst/dev/maicplus/maicplus-main/bucher.R index c30fbde1..4b7b5c5f 100644 --- a/inst/dev/maicplus/maicplus-main/bucher.R +++ b/inst/dev/maicplus/maicplus-main/bucher.R @@ -5,24 +5,24 @@ #' #' @param trt a list with two named scalars for the study with interested experimental arm, one named 'est' for the point estimate, and the other named 'se' for the standard error #' @param com same as \code{trt} for the study with interested control arm -#' @param conf.lv a numerical scalar, prescribe confidence level to derive two-sided confidence interval for the adjusted treatment effect +#' @param conf_lv a numerical scalar, prescribe confidence level to derive two-sided confidence interval for the adjusted treatment effect #' #' @return a list with 5 elements, #' \describe{ #' \item est - a scalar, point estimate of the adjusted treatment effect #' \item se - a scalar, standard error of the adjusted treatment effect (i.e. \code{est} in return) -#' \item ci_l - a scalor, lower confidence limit of a two-sided CI with prescribed nominal level by \code{conf.lv} -#' \item ci_u - a scalor, upper confidence limit of a two-sided CI with prescribed nominal level by \code{conf.lv} +#' \item ci_l - a scalor, lower confidence limit of a two-sided CI with prescribed nominal level by \code{conf_lv} +#' \item ci_u - a scalor, upper confidence limit of a two-sided CI with prescribed nominal level by \code{conf_lv} #' \item pval - p-value of Z-test, with null hypothesis that \code{est} is zero #' } #' @export #' #' @examples -bucher <- function(trt, com, conf.lv = 0.95) { +bucher <- function(trt, com, conf_lv = 0.95) { est <- trt$est - com$est se <- sqrt(trt$se^2 + com$se^2) - ci_l <- est - qnorm(0.5 + conf.lv / 2) * se - ci_u <- est + qnorm(0.5 + conf.lv / 2) * se + ci_l <- est - qnorm(0.5 + conf_lv / 2) * se + ci_u <- est + qnorm(0.5 + conf_lv / 2) * se if (est > 0) { pval <- 2 * (1 - pnorm(est, 0, se)) } else { diff --git a/man/bucher.Rd b/man/bucher.Rd new file mode 100644 index 00000000..df3f8b17 --- /dev/null +++ b/man/bucher.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/bucher.R +\name{bucher} +\alias{bucher} +\title{Bucher method for adjusted treatment effect} +\usage{ +bucher(trt, com, conf_lv = 0.95) +} +\arguments{ +\item{trt}{a list with two named scalars for the study with interested experimental arm, +one named \code{'est'} for the point estimate, and the other named \code{'se'} for the standard error} + +\item{com}{same as \code{trt}, but for the study with interested control arm} + +\item{conf_lv}{a numerical scalar, prescribe confidence level to derive two-sided +confidence interval for the adjusted treatment effect} +} +\value{ +a list with 5 elements, +\describe{ +\item{est}{a scalar, point estimate of the adjusted treatment effect} +\item{se}{a scalar, standard error of the adjusted treatment effect (i.e. \code{est} in return)} +\item{ci_l}{a scalar, lower confidence limit of a two-sided CI with prescribed nominal level by \code{conf_lv}} +\item{ci_u}{a scalar, upper confidence limit of a two-sided CI with prescribed nominal level by \code{conf_lv}} +\item{pval}{p-value of Z-test, with null hypothesis that \code{est} is zero} +} +} +\description{ +Given two estimated treatment effects of A vs. C and B vs. C +(i.e. two point estimates and corresponding standard errors), +derive the adjusted treatment of A vs. B using Bucher method, +with two-sided confidence limits and Z-test p-value +} diff --git a/man/center_ipd.Rd b/man/center_ipd.Rd new file mode 100644 index 00000000..bd07af2d --- /dev/null +++ b/man/center_ipd.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/process_data.R +\name{center_ipd} +\alias{center_ipd} +\title{Center effect modifiers} +\usage{ +center_ipd(ipd, agd) +} +\arguments{ +\item{agd}{} +} +\description{ +Center effect modifiers +} diff --git a/man/complete_agd.Rd b/man/complete_agd.Rd new file mode 100644 index 00000000..9a087c84 --- /dev/null +++ b/man/complete_agd.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/process_data.R +\name{complete_agd} +\alias{complete_agd} +\title{Calculate pooled arm statistics in Aggregated Data (AgD) based on arm-specific statistics} +\usage{ +complete_agd(use_agd) +} +\arguments{ +\item{use_agd}{} +} +\description{ +Calculate pooled arm statistics in Aggregated Data (AgD) based on arm-specific statistics +} diff --git a/man/estimate_weights.Rd b/man/estimate_weights.Rd new file mode 100644 index 00000000..0dd5eb5c --- /dev/null +++ b/man/estimate_weights.Rd @@ -0,0 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/matching.R +\name{estimate_weights} +\alias{estimate_weights} +\title{Derive individual weights in the matching step of MAIC} +\usage{ +estimate_weights( + data, + centered_colnames = NULL, + startVal = 0, + method = "BFGS", + ... +) +} +\arguments{ +\item{data}{a numeric matrix, centered effect modifiers of IPD, no missing value in any cell is allowed} + +\item{centered_colnames}{a character or numeric vector, column indicators of centered effect modifiers, by default NULL meaning all columns in \code{data} are effect modifiers} + +\item{startVal}{a scalar, the starting value for all coefficients of the propensity score regression} + +\item{method}{a string, name of the optimization algorithm (see 'method' argument of \code{base::optim()}). +The default is \code{"BFGS"}, other options are \code{"Nelder-Mead"}, \code{"CG"}, \code{"L-BFGS-B"}, \code{"SANN"}, and \code{"Brent"}} + +\item{...}{all other arguments from \code{base::optim()}} +} +\value{ +a list with the following 4 elements, +\describe{ +\item{data}{a data.frame, includes the input \code{data} with appended column 'weights' and 'scaled_weights'. +Scaled weights has a summation to be the number of rows in \code{data} that has no missing value in any of the effect modifiers} +\item{centered.colnames}{column names of centered effect modifiers in \code{data}} +\item{nr_missing}{number of rows in \code{data} that has at least 1 missing value in specified centered effect modifiers} +\item{ess}{effective sample size, square of sum divided by sum of squares} +\item{opt}{R object returned by \code{base::optim()}, for assess convergence and other details} +} +} +\description{ +Assuming data is properly processed, this function takes individual patient data (IPD) with centered effect modifiers as input, +and generates weights for each individual in IPD trial that matches the chosen statistics of those effect modifiers in Aggregated Data (AgD) trial. +} diff --git a/man/ext_tte_transfer.Rd b/man/ext_tte_transfer.Rd new file mode 100644 index 00000000..befc58c7 --- /dev/null +++ b/man/ext_tte_transfer.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/process_data.R +\name{ext_tte_transfer} +\alias{ext_tte_transfer} +\title{helper function: transform TTE ADaM data to suitable input for survival R pkg} +\usage{ +ext_tte_transfer(dd, time_scale = "month", trt = NULL) +} +\arguments{ +\item{dd}{data frame, ADTTE read via \code{haven::read_sas()}} + +\item{time_scale}{a character string, 'year', 'month', 'week' or 'day', time unit of median survival time} +} +\value{ +a data frame can be used as input to \code{\link[survival:Surv]{survival::Surv()}} +} +\description{ +helper function: transform TTE ADaM data to suitable input for survival R pkg +} diff --git a/man/km_makeup.Rd b/man/km_makeup.Rd new file mode 100644 index 00000000..e218cc2c --- /dev/null +++ b/man/km_makeup.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/survival-helper.R +\name{km_makeup} +\alias{km_makeup} +\title{helper function: KM plot with unadjusted and adjusted KM} +\usage{ +km_makeup( + km_fit_before, + km_fit_after = NULL, + time_scale, + trt, + trt_ext, + endpoint_name = "" +) +} +\arguments{ +\item{km_fit_before}{returned object from \code{survival::survfit} before adjustment} + +\item{km_fit_after}{returned object from \code{survival::survfit} after adjustment} + +\item{time_scale}{a character string, 'year', 'month', 'week' or 'day', time unit of median survival time} + +\item{trt}{a character string, name of the interested treatment in internal trial (real IPD)} + +\item{trt_ext}{character string, name of the interested comparator in external trial used to subset \code{dat_ext} (pseudo IPD)} + +\item{endpoint_name}{a character string, name of the endpoint} +} +\value{ +a KM plot +} +\description{ +helper function: KM plot with unadjusted and adjusted KM +} diff --git a/man/log_cum_haz_plot.Rd b/man/log_cum_haz_plot.Rd new file mode 100644 index 00000000..de43a5a9 --- /dev/null +++ b/man/log_cum_haz_plot.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/survival-helper.R +\name{log_cum_haz_plot} +\alias{log_cum_haz_plot} +\title{Plot Log Cumulative Hazard Rate} +\usage{ +log_cum_haz_plot( + clldat, + time_scale, + log_time = TRUE, + endpoint_name = "", + subtitle = "", + exclude_censor = TRUE +) +} +\arguments{ +\item{clldat}{object returned from \code{\link{survfit_makeup}}} + +\item{time_scale}{a character string, 'year', 'month', 'week' or 'day', time unit of median survival time} + +\item{log_time}{logical, TRUE (default) or FALSE} + +\item{endpoint_name}{a character string, name of the endpoint} + +\item{subtitle}{a character string, subtitle of the plot} + +\item{exclude_censor}{logical, should censored data point be plotted} +} +\value{ +a plot +} +\description{ +a diagnosis plot for proportional hazard assumption, versus log-time (default) or time +} diff --git a/man/maic_tte_unanchor.Rd b/man/maic_tte_unanchor.Rd new file mode 100644 index 00000000..1cdd650a --- /dev/null +++ b/man/maic_tte_unanchor.Rd @@ -0,0 +1,45 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/maic_unanchored_tte.R +\name{maic_tte_unanchor} +\alias{maic_tte_unanchor} +\title{Unanchored MAIC for time-to-event endpoint} +\usage{ +maic_tte_unanchor( + useWt, + dat, + dat_ext, + trt, + trt_ext, + time_scale = "month", + endpoint_name = "OS", + transform = "log" +) +} +\arguments{ +\item{useWt}{a numeric vector of individual MAIC weights, length should the same as \code{nrow(dat)}} + +\item{dat}{a data frame that meet format requirements in 'Details', individual patient data (IPD) of internal trial} + +\item{dat_ext}{a data frame, pseudo IPD from digitized KM curve of external trial} + +\item{trt}{a character string, name of the interested treatment in internal trial (real IPD)} + +\item{trt_ext}{character string, name of the interested comparator in external trial used to subset \code{dat_ext} (pseudo IPD)} + +\item{time_scale}{a character string, 'year', 'month', 'week' or 'day', time unit of median survival time} + +\item{endpoint_name}{a character string, name of the endpoint} + +\item{transform}{a character string, pass to \code{\link[survival]{cox.zph}}} +} +\description{ +Unanchored MAIC for time-to-event endpoint +} +\details{ +Format requirements for input \code{dat} and \code{dat_ext} are to have the following columns +\itemize{ +\item treatment - character or factor column +\item status - logical column, TRUE for censored/death, FALSE for otherwise +\item time - numeric column, observation time of the \code{status}; unit in days +} +} diff --git a/man/medSurv_makeup.Rd b/man/medSurv_makeup.Rd new file mode 100644 index 00000000..77b7b894 --- /dev/null +++ b/man/medSurv_makeup.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/survival-helper.R +\name{medSurv_makeup} +\alias{medSurv_makeup} +\title{helper function: makeup to get median survival time from a \code{survival::survfit} object} +\usage{ +medSurv_makeup(km_fit, legend = "before matching", time_scale) +} +\arguments{ +\item{km_fit}{returned object from \code{survival::survfit}} + +\item{legend}{a character string, name used in 'type' column in returned data frame} + +\item{time_scale}{a character string, 'year', 'month', 'week' or 'day', time unit of median survival time} +} +\value{ +a data frame with a index column 'type', median survival time and confidence interval +} +\description{ +extract and display median survival time with confidence interval +} diff --git a/man/plot_weights.Rd b/man/plot_weights.Rd new file mode 100644 index 00000000..e2644e2a --- /dev/null +++ b/man/plot_weights.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/matching.R +\name{plot_weights} +\alias{plot_weights} +\title{Plot MAIC weights in a histogram with key statistics in legend} +\usage{ +plot_weights(wt, main_title = "Unscaled Individual Weigths") +} +\arguments{ +\item{wt}{a numeric vector of individual MAIC weights (derived use in \code{\link{cal_weights}})} + +\item{main_title}{a character string, main title of the plot} +} +\value{ +a plot +} +\description{ +Generates a plot given the individuals weights with key summary in top right legend that +includes median weight, effective sample size (ESS), reduction percentage (what percent +ESS takes up in the original sample size), +} diff --git a/man/print_bucher.Rd b/man/print_bucher.Rd new file mode 100644 index 00000000..78e6e5a0 --- /dev/null +++ b/man/print_bucher.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/bucher.R +\name{print_bucher} +\alias{print_bucher} +\title{Report-friendly output format for result from Bucher's method} +\usage{ +print_bucher(output, ci_digits = 2, pval_digits = 3) +} +\arguments{ +\item{output}{output from \code{\link{bucher}} function} + +\item{ci_digits}{an integer, number of decimal places for point estimate and derived confidence limits} + +\item{pval_digits}{an integer, number of decimal places to display Z-test p-value} +} +\value{ +a character vector of two elements, first element in format of 'est (ci_l; ci_u)'`, +second element is the Z-test p-value, rounded according to \code{pval_digits} +} +\description{ +Report-friendly output format for result from Bucher's method +} diff --git a/man/process_agd.Rd b/man/process_agd.Rd new file mode 100644 index 00000000..5e7e7103 --- /dev/null +++ b/man/process_agd.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/process_data.R +\name{process_agd} +\alias{process_agd} +\title{Process and Check Aggregated data format} +\usage{ +process_agd(raw_agd) +} +\arguments{ +\item{raw_agd}{} +} +\description{ +Process and Check Aggregated data format +} diff --git a/man/process_ipd.Rd b/man/process_ipd.Rd new file mode 100644 index 00000000..61feb90c --- /dev/null +++ b/man/process_ipd.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/process_data.R +\name{process_ipd} +\alias{process_ipd} +\title{Process Individual Patient data categorical effective modifiers to dummy variables} +\usage{ +process_ipd(raw_ipd, dummize_cols, dummize_ref_level) +} +\arguments{ +\item{dummize_ref_level}{} +} +\description{ +Process Individual Patient data categorical effective modifiers to dummy variables +} diff --git a/man/report_table.Rd b/man/report_table.Rd new file mode 100644 index 00000000..9a76f394 --- /dev/null +++ b/man/report_table.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/maic_unanchored_tte.R +\name{report_table} +\alias{report_table} +\title{helper function: sort out a nice report table to summarize survival analysis results +for \code{maic_tte_unanchor}} +\usage{ +report_table(coxobj, medSurvobj, tag = NULL) +} +\arguments{ +\item{coxobj}{returned object from \code{\link[survival]{coxph}}} + +\item{medSurvobj}{returned object from \code{\link{medSurv_makeup}}} + +\item{tag}{a string, by default NULL, if specified, an extra 1st column is created in the output} +} +\value{ +a data frame with sample size, incidence rate, median survival time with 95\% CI, hazard ratio estimate with +95\% CI and Wald test of hazard ratio +} +\description{ +helper function: sort out a nice report table to summarize survival analysis results +for \code{maic_tte_unanchor} +} diff --git a/man/resid_plot.Rd b/man/resid_plot.Rd new file mode 100644 index 00000000..e5e452e9 --- /dev/null +++ b/man/resid_plot.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/survival-helper.R +\name{resid_plot} +\alias{resid_plot} +\title{Plot Schoenfeld residuals for a Cox model fit} +\usage{ +resid_plot( + coxobj, + time_scale = "month", + log_time = TRUE, + endpoint_name = "", + subtitle = "" +) +} +\arguments{ +\item{coxobj}{object returned from \code{\link[survival]{coxph}}} + +\item{time_scale}{a character string, 'year', 'month', 'week' or 'day', time unit of median survival time} + +\item{log_time}{logical, TRUE (default) or FALSE} + +\item{endpoint_name}{a character string, name of the endpoint} + +\item{subtitle}{a character string, subtitle of the plot} +} +\value{ +a plot +} +\description{ +Plot Schoenfeld residuals for a Cox model fit +} diff --git a/man/survfit_makeup.Rd b/man/survfit_makeup.Rd new file mode 100644 index 00000000..6c5b3557 --- /dev/null +++ b/man/survfit_makeup.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/survival-helper.R +\name{survfit_makeup} +\alias{survfit_makeup} +\title{helper function: makeup \code{survival::survfit} object for km plot} +\usage{ +survfit_makeup(km_fit) +} +\arguments{ +\item{km_fit}{returned object from \code{survival::survfit}} +} +\value{ +a list of data frames, one element per treatment +} +\description{ +helper function: makeup \code{survival::survfit} object for km plot +} diff --git a/tests/testthat/test-bucher.R b/tests/testthat/test-bucher.R new file mode 100644 index 00000000..88ffe7b5 --- /dev/null +++ b/tests/testthat/test-bucher.R @@ -0,0 +1,16 @@ +test_that("bucher works as expected", { + result <- bucher( + trt = list(est = 1, se = 0.04), + com = list(est = 1.2, se = 0.08), + conf_lv = 0.9 + ) + + expected <- list( + est = -0.2, + se = 0.0894427190999916, + ci_l = -0.347120180916023, + ci_u = -0.0528798190839771, + pval = 0.0253473186774683 + ) + expect_equal(result, expected) +})