Sys.setlocale("LC_ALL","English") # for english day of week

Summary

Clinical researchers are often overly optimistic with regards to their institutions capacity to enroll participants into their trials. A common failing point in clinical trials is thus poor recruitment, which leads to extended trial duration, and concomitantly increased costs. In the worst case, the trial may be shut down before enough participants have been recruited to show an effect [@fogel2018]. Amongst other things, the International Conference on Harmonization (ICH) Good Clinical Practice (GCP) guideline addendum E6 (R2) highlights the need for risk based monitoring, which partially addresses this topic. Appropriate monitoring should identify the problem early, providing a chance to optimise the recruitment strategy and/or initiate new trial sites. accrualPlot provides tools to summarize recruitment and predict the end date for the target sample size, thereby assisting with monitoring the risk of poor recruitment. accrualPlot is available from CRAN and additional information is available at the package site.

Example usage

accrualPlot is installed via install.packages("accrualPlot"), and loaded into the R session via library(accrualPlot).

The package includes a demonstration data set called accrualdemo, which we shall use to show the features of the package.

library(accrualPlot)
data("accrualdemo")

The first step to using accrualPlot is to create an accrual_df as follows. At this point, if we know when each site opened, we can pass a vector of dates to the start_date argument. We can also indicate the current date (via the current_date argument), which can be relevant when there have been no new participants enrolled recently. The by, start_date and current_date arguments are all optional.

acc <- accrual_create_df(enrollment_dates = accrualdemo$date, 
                         by = accrualdemo$site, 
                         start_date = c("Site 1" = as.Date("2020-07-01"), 
                                        "Site 2" = as.Date("2020-07-13"), 
                                        "Site 3" = as.Date("2020-08-25")))

A short summary table of recruitment at the sites (if entered, only overall otherwise) is accessed via summary.

summary(acc, header = FALSE)

We can also plot the cumulative (by default for individual sites and overall) and absolute recruitment (per day, week, month, etc).

par(mfrow = c(1,2))
plot(acc)
plot(acc, which = "abs")

It is also possible predict the date at which the recruitment target would be achieved by setting which = "pred" and the target argument.

plot(acc, which = "pred", target = 500, 
     center_legend = "strip")

By default, the most recent observation gets most weight and oldest the least (i.e. seq(1/N, 1, by = 1/N)). To change that to the last 30 days where each day gets equal weight, for example, pass a function to the wfun argument which returns the appropriate weights.

plot(acc, which = "pred", target = 500, 
     wfun = function(x) ifelse(x$Date > (max(x$Date) - 30), 1, 0))

For those that prefer ggplot2 graphics, the engine = "ggplot" argument to plot can be used to return ggplot objects instead of base graphics plots. Dedicated functions for each plot in both 'engines' also exist, so the use of plot is not strictly necessary. An example of using the function to create the ggplot2 variants follows, including using the dedicated function for the prediction plot.

library(patchwork)
(plot(acc, engine = "ggplot") + 
    ggplot2::theme(legend.position = "bottom") +
  plot(acc, "abs", engine = "ggplot") + 
    ggplot2::theme(legend.position = "bottom")) /
  gg_accrual_plot_predict(acc, target = 500)

Acknowledgements

We acknowledge contributions from Nick Fankhauser, who wrote an early version of the code, and other statisticians from CTU Bern for testing and suggestions while developing this software.

References



CTU-Bern/accrualPlot documentation built on Aug. 17, 2024, 8:20 p.m.