Skip to content

Commit b1b7db8

Browse files
committed
Update binary endpoint standard error calculation
1 parent f5b77f5 commit b1b7db8

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

R/internal.R

+34-10
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@
181181
poss_comb <- expand.grid("outcome" = step_outcomes,
182182
"arm" = arm_levels)
183183
missing_row <- dplyr::anti_join(poss_comb,
184-
hce_ecdf[, c("outcome", "arm")])
184+
hce_ecdf[, c("outcome", "arm")],
185+
by = c("outcome", "arm"))
185186

186187
# If there are missing rows, fill them in
187188
if (nrow(missing_row) > 0) {
@@ -304,12 +305,16 @@
304305
`%>%` <- dplyr::`%>%`
305306
n <- dplyr::n
306307

308+
# Extract the active and control arm treatment names
307309
actv <- unname(arm_levels["active"])
308310
ctrl <- unname(arm_levels["control"])
309311

312+
# Retrieve hce data for the last outcome as well as the x-axis position
313+
# to start from
310314
binary_data <- hce_dat[hce_dat$outcome == last_outcome, ]
311315
start_binary_endpoint <- meta[meta$outcome == last_outcome, ]$startx
312316

317+
# Get the y-values that the step outcomes ended on for both arms
313318
actv_y <- ecdf_mod$meta[
314319
ecdf_mod$meta$arm == actv &
315320
ecdf_mod$meta$outcome == utils::tail(step_outcomes, 1),
@@ -319,30 +324,41 @@
319324
ecdf_mod$meta$outcome == utils::tail(step_outcomes, 1),
320325
]$ecdf_end
321326

327+
# Calculate difference of proportion statistics for each arm (estimate
328+
# and lower confidence interval boundary) using prop.test
329+
# Note: we are using percentages rather than proportions (*100)
322330
binary_meta <- binary_data %>%
323331
dplyr::group_by(arm) %>%
324332
dplyr::summarise(n = n(),
325-
average = base::mean(value, na.rm = TRUE),
326-
conf_int = 1.96 * sqrt((average * (1 - average)) / n)) %>%
333+
x = base::sum(value, na.rm = TRUE),
334+
average = 100 *
335+
as.numeric(stats::prop.test(x, n)$estimate),
336+
se = abs(average - (100 *
337+
as.numeric(stats::prop.test(x, n)$conf.int)[1]))) %>%
327338
dplyr::ungroup()
328339

329-
x_radius <- (100 - start_binary_endpoint) * min(binary_meta$conf_int)
330-
y_height <- min(c(0.4 * abs(actv_y - ctrl_y), 0.8 * x_radius))
340+
# To create ellipsis shape and avoid overlapping between both of them,
341+
# set the height to 80% of the SE (minimum scaled in x-axis or y-axis range)
342+
width <- (100 - start_binary_endpoint) * min(binary_meta$se) / 100
343+
y_range <- (max(actv_y, ctrl_y) + 10) * min(binary_meta$se) / 100
344+
y_height <- min(c(0.4 * abs(actv_y - ctrl_y), 0.8 * min(width, y_range)))
331345

346+
# Create ellipsis centered around proportion estimate (x0) as well as
347+
# y-value that the step outcomes ended on for each arm,
348+
# with the standard error as width and the height as calculated above
332349
actv_point <-
333350
.create_ellipsis_points(unlist(binary_meta[binary_meta$arm == actv,
334351
"average"]),
335352
actv_y,
336353
unlist(binary_meta[binary_meta$arm == actv,
337-
"conf_int"]),
354+
"se"]),
338355
y_height)
339-
340356
ctrl_point <-
341357
.create_ellipsis_points(unlist(binary_meta[binary_meta$arm == ctrl,
342358
"average"]),
343359
ctrl_y,
344360
unlist(binary_meta[binary_meta$arm == ctrl,
345-
"conf_int"]),
361+
"se"]),
346362
y_height)
347363

348364
binary_data <- rbind(data.frame("outcome" = last_outcome,
@@ -357,14 +373,14 @@
357373
binary_data$x,
358374
start_binary_endpoint,
359375
0,
360-
1
376+
100
361377
)
362378

363379
binary_meta$average <- .to_rangeab(
364380
binary_meta$average,
365381
start_binary_endpoint,
366382
0,
367-
1
383+
100
368384
)
369385

370386
binary_meta$y <- 0
@@ -377,13 +393,21 @@
377393
))
378394
}
379395

396+
# Create ellipsis centered around point (x0,y0),
397+
# with range (x0+a,y0+b)
380398
.create_ellipsis_points <- function(x0, y0, a, b) {
381399

400+
# First create equally spaced points on a unit
401+
# circle (with x-coordinates cos_p and y-coordinates
402+
# sin_p), ranging from -1 to 1
382403
points <- seq(0, 2 * pi, length.out = 361)
383404
cos_p <- cos(points)
384405
sin_p <- sin(points)
406+
# Change the shape by changing the x-axis range (to 2*a)
407+
# and y axis range (to 2*b)
385408
x_tmp <- abs(cos_p) * a * sign(cos_p)
386409
y_tmp <- abs(sin_p) * b * sign(sin_p)
410+
# Move x and y values to be centered around x0 and y0
387411
edata <- data.frame(x = x0 + x_tmp, y = y0 + y_tmp)
388412

389413
return(edata)

R/maraca.R

+2-2
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,8 @@ plot_maraca <- function(
412412

413413
} else if (last_type == "binary") {
414414

415-
minor_grid <- seq(0, 1, continuous_grid_spacing_x)
416-
range <- c(0, 1)
415+
minor_grid <- seq(0, 100, continuous_grid_spacing_x)
416+
range <- c(0, 100)
417417

418418
}
419419

0 commit comments

Comments
 (0)