diff --git a/R/internal.R b/R/internal.R index 4067840..e765bb3 100644 --- a/R/internal.R +++ b/R/internal.R @@ -285,7 +285,7 @@ # To create ellipsis shape and avoid overlapping between both of them, # set the height to 80% of the SE (minimum scaled in x-axis or y-axis range) width <- (100 - start_binary_endpoint) * min(binary_meta$se) / 100 - y_range <- (max(actv_y, ctrl_y) + 10) * min(binary_meta$se) / 100 + y_range <- ((max(actv_y, ctrl_y) + 10) * min(binary_meta$se) / 100) * 0.6 y_height <- min(c(0.4 * abs(actv_y - ctrl_y), 0.8 * min(width, y_range))) # Create ellipsis centered around proportion estimate (x0) as well as diff --git a/R/internal_winOdds.R b/R/internal_winOdds.R index 2dcc0a6..a25bb51 100644 --- a/R/internal_winOdds.R +++ b/R/internal_winOdds.R @@ -54,8 +54,9 @@ GROUP = "outcome") endpoints <- c(step_outcomes, last_outcome) - labs <- c(Reduce(paste, as.character(endpoints[1:(length(endpoints) - 1)]), - accumulate = TRUE), "All") + labs <- c(sapply(head(seq_along(endpoints), -1), function(i) { + paste(endpoints[1:i], collapse = " +\n") + }), "All") hce_dat <- hce_dat %>% dplyr::mutate_at(dplyr::vars(outcome), factor, levels = c(endpoints, "X")) @@ -208,11 +209,18 @@ if (theme != "none") { plot <- plot + - theme_bw() + - theme(legend.position = "bottom", legend.title = element_blank()) + + ggplot2::geom_vline(xintercept = + seq(0.5, length(levels(wins_forest$GROUP)) + 1.5, + 1), + linetype = 2, linewidth = 0.3, color = "darkgray") + scale_color_manual(values = c("black", "grey50")) + scale_fill_manual(values = c("black", "grey50")) + - ylab("Win Odds / Win Ratio") + ylab("Win Odds / Win Ratio") + + theme_bw() + + theme(legend.position = "bottom", + legend.title = element_blank(), + panel.grid.major.y = ggplot2::element_blank(), + panel.grid.minor.y = ggplot2::element_blank()) } return(plot) diff --git a/R/winOddsPlots.R b/R/winOddsPlots.R index 14c4a7e..5cec958 100644 --- a/R/winOddsPlots.R +++ b/R/winOddsPlots.R @@ -225,7 +225,7 @@ cumulative_plot.maraca <- function(x, theme = "maraca", ...) { plot_forest <- .create_forest_plot(wins_forest, theme) plot <- patchwork:::"|.ggplot"(plot_bar, plot_forest) + - patchwork::plot_layout(widths = c(3, 1), nrow = 1) + patchwork::plot_layout(widths = c(2.5, 1), nrow = 1) # Add class to plot - cumulativePlot class(plot) <- c("cumulativePlot", class(plot)) diff --git a/vignettes/otherEndpoints.Rmd b/vignettes/otherEndpoints.Rmd new file mode 100644 index 0000000..47112e3 --- /dev/null +++ b/vignettes/otherEndpoints.Rmd @@ -0,0 +1,180 @@ +--- +title: "Maraca Plots - Alternative Endpoints" +author: "Monika Huhn" +date: "`r Sys.Date()`" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Maraca Plots - Alternative Endpoints} + %\VignetteEngine{knitr::rmarkdown} + \usepackage[utf8]{inputenc} +--- + +```{r setup, include = FALSE} +knitr::opts_chunk$set(echo = TRUE, collapse = TRUE) +library(dplyr) +library(maraca) +``` + +The maraca package can also be used for hierarchical endpoints containing other type of endpoints than +time-to-event and continuous. Currently binary endpoints are also supported with further type of +endpoints under development + + +## Binary endpoints + +### Last outcome + +First we go through an example where the final outcome instead of being continuous, is a binary outcome. +As an example, this could for example be weight loss above a certain threshold at the end of the study. +The way the outcome should be included in the data is as a numeric vector with 1 for those patients that +had the outcome and 0 for those that had not. + +We do not have any example dataset with a final binary endpoint included in the package, so for +this vignette we modify an existing dataset: + +```{r} +data("hce_scenario_a") +# Create data with binary version of continuous final endpoint +bin_data <- hce_scenario_a +# Index of all continuous outcome rows +idx_cont <- bin_data$GROUP == "Continuous outcome" +# Rename outcome +bin_data[idx_cont,"GROUP"] <- "Binary outcome" +# Binary version (>= 0/< 0) +bin_data[idx_cont,"AVAL0"] <- bin_data[idx_cont,"AVAL0"] >= 0 +bin_data[idx_cont,"AVAL"] <- bin_data[idx_cont,"AVAL0"] + + bin_data[idx_cont,"GROUPN"] +head(bin_data) +``` + +If we now want to create a maraca object for this data, we need to slightly update +the default code. By default, maraca expects the last outcome to be continuous. In +order for the function to know that the last outcome is binary, we have to update +the parameter `last_type`. The parameter currently accepts the inputs `"binary"` and +`"continuous"`. +```{r} +column_names <- c( + outcome = "GROUP", + arm = "TRTP", + value = "AVAL0" +) + +step_outcomes <- c("Outcome I", "Outcome II", + "Outcome III", "Outcome IV") + +last_outcome <- "Binary outcome" + +arm_levels <- c(active = "Active", + control = "Control") + +mar <- maraca( + bin_data, step_outcomes, last_outcome, + arm_levels, column_names, + fixed_followup_days = 3*365, + compute_win_odds = TRUE, + # Important change: Add information that last endpoint is + # not continuous (the default) + last_type = "binary" +) +``` + +The maraca object can now be plotted. A binary endpoint is plotted +as an ellipsis. The point in the middle of the ellipsis indicates the +proportion that has met the binary endpoint. The width of the ellipsis +(x-axis range) shows the confidence interval. +Specifying `vline_type = "mean"` (the default) will add vertical lines +indicating the proportions in each treatment group for easier readibility. +Note that `vline_type = "median"` (the default for continuous endpoints) +will result in an error. The same is true for setting `density_plot_type` to +anything other than `"default"`. +```{r fig.width = 7, fig.height = 6} +plot(mar) +``` + + +### Step outcome + +What if the binary outcome is not the last outcome of the hierarchical endpoint +but rather one (or several) of the previous outcomes? So rather than solely having +time-to-event endpoints within the step function part of the plot, we also have +at least one binary (so not time depending) variable. +To include a binary variable, we expect the data for this outcome to include only +patients that had the outcome and they all have to have the original analysis value 1. + +Let's create a dataset with 2 binary outcomes. +```{r} +data("hce_scenario_a") +# Create data with binary version of continuous final endpoint +bin_data2 <- hce_scenario_a +# Index of all continuous outcome rows +idx_bin <- bin_data2$GROUP %in% c("Outcome III", "Outcome IV") +# Binary version (>= 0/< 0), coded as 1 +bin_data2[idx_bin,"AVAL0"] <- bin_data2[idx_bin,"AVAL0"] >= 500 +bin_data2[idx_bin,"AVAL"] <- bin_data2[idx_bin,"AVAL0"] + + bin_data2[idx_bin,"GROUPN"] +# Remove 0 rows (only include patients that had the outcome) +bin_data2 <- bin_data2[bin_data2$AVAL0 != 0,] +head(bin_data2) +``` + +Again we need to slightly update the default code if we want to create a maraca object +for this data. By default, maraca expects all the step outcomes to be time-to-event +endpoints. In order for the function to know that there are binary outcomes, we have to +update the parameter `step_types`. The parameter currently accepts the inputs `"binary"` and +`"tte"`. If all the step outcomes are of the same type, the user can give the type as a string +(such as by default `step_types = "tte"`). If there are different endpoint types, then the user +has to provide a vector with one element for each step outcome. +Similarly, the fixed-follow up time can be given as a single number or a vector. Note that the +fixed-follow-up time is only needed for time-to-event endpoints, so if providing a vector then +it should contain one value for each time-to-event endpoint. +```{r} +column_names <- c( + outcome = "GROUP", + arm = "TRTP", + value = "AVAL0" +) + +step_outcomes <- c("Outcome I", "Outcome II", + "Outcome III", "Outcome IV") + +last_outcome <- "Continuous outcome" + +arm_levels <- c(active = "Active", + control = "Control") + +mar <- maraca( + bin_data2, step_outcomes, last_outcome, + arm_levels, column_names, + fixed_followup_days = 3*365, + compute_win_odds = TRUE, + # Important change: Add information that last endpoint is + # not continuous (the default) + step_types = c("tte","tte","binary","binary") +) +``` + +Again, we can plot the final object. +```{r fig.width = 7, fig.height = 6} +plot(mar) +``` + + +As with all maraca objects, the different plotting parameters can be +used. + +```{r fig.width = 7, fig.height = 6} +plot(mar, continuous_grid_spacing_x = 20, + theme = "color1") +``` + +Also, the win odds plots can be created as usual. +```{r fig.width = 7, fig.height = 6} +component_plot(mar, + theme = "color2") +``` + +```{r fig.width = 7, fig.height = 6} +cumulative_plot(mar, + theme = "color1") +``` + diff --git a/vignettes/winOdds.Rmd b/vignettes/winOdds.Rmd index c9098f0..846021d 100644 --- a/vignettes/winOdds.Rmd +++ b/vignettes/winOdds.Rmd @@ -76,9 +76,51 @@ hce_dat <- simHCE(n = 2500, TTE_A = Rates_A, TTE_P = Rates_P, component_plot(hce_dat) ``` +## Cumulative plot + +Furthermore, there is also a plot called `"cumulative_plot"`. +Similar as above, this plot shows the different components that +make up the win odds calculation. Different to the component plot, +this plot shows the endpoint cumulated instead (adding one +hierarchical endpoint at a time). +As explained above, the plot shows how +often patients in the active arm "won" or "lost" against the other +arm or if they had a "tie". + +As before, in order to use the `cumulative_plot`, we have to first create a +`maraca` object. Important here is to set the argument +`compute_win_odds = TRUE`, so that the necessary calculations +are included. +```{r} +maraca_dat <- maraca( + data = hce_scenario_a, + step_outcomes = c("Outcome I", "Outcome II", "Outcome III", "Outcome IV"), + last_outcome = "Continuous outcome", + fixed_followup_days = 3 * 365, + column_names = c(outcome = "GROUP", arm = "TRTP", value = "AVAL0"), + arm_levels = c(active = "Active", control = "Control"), + # Make sure to calculate the win odds + compute_win_odds = TRUE +) +``` + +Now we can just plot the object using the `cumulative_plot()` function. +```{r fig.width=7, fig.height=6} +cumulative_plot(maraca_dat) +``` + +It is also possible to use the `cumulative_plot()` function directly on +an `hce` object (created using the +[hce package](https://cran.r-project.org/package=hce)). + +```{r fig.width=7, fig.height=6} +cumulative_plot(hce_dat) +``` + ## Styling -The resulting plot is a normal ggplot2 object that can be styled accordingly. +The resulting plots for both the `component_plot()` and `cumulative_plot()` functions +are normal ggplot2 objects that can be styled accordingly. There are also different themes available to style the plot. The default style is called `theme = "maraca"`. @@ -89,7 +131,7 @@ component_plot(maraca_dat, theme = "maraca") There are 2 different themes with different color schemes, `theme = "color1"` and `theme = "color2"`. ```{r fig.width=7, fig.height=6} -component_plot(maraca_dat, theme = "color1") +cumulative_plot(maraca_dat, theme = "color1") ``` ```{r fig.width=7, fig.height=6} @@ -98,5 +140,5 @@ component_plot(maraca_dat, theme = "color2") There is also a theme without any styling `theme = "none"`. ```{r fig.width=8, fig.height=6} -component_plot(maraca_dat, theme = "none") +cumulative_plot(maraca_dat, theme = "none") ```