Skip to content

Commit a5713f8

Browse files
committed
changed from hardcoded A,B,C to something more generic. Its still a bit hacky but the binomial data examples seems to work ok. Need to check the other data types n ext.
closes #35
1 parent 4264e3d commit a5713f8

19 files changed

+302
-165
lines changed

NAMESPACE

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export(strategy_gcomp_stan)
3131
export(strategy_maic)
3232
export(strategy_mim)
3333
export(strategy_stc)
34-
import(plyr)
3534
import(stats)
3635
import(stringr)
3736
import(tidyr)

R/calc_IPD_stats.R

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,14 @@ calc_IPD_stats.mim <- function(strategy,
7474
lci.Delta <- coef_est + qt(0.025, df = nu) * sqrt(var_est)
7575
uci.Delta <- coef_est + qt(0.975, df = nu) * sqrt(var_est)
7676

77-
list(mean = coef_est,
78-
var = var_est)
77+
list(
78+
contrasts = list(
79+
mean = coef_est,
80+
var = var_est),
81+
absolute = list(
82+
mean = NA, #p_est, ##TODO:
83+
var = NA) #p_var)
84+
)
7985
}
8086

8187
#' Factory function for creating calc_IPD_stats methods

R/calc_stc.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#'
66
calc_stc <- function(strategy, ipd, ...) {
77

8-
treat_nm <- strategy$trt_var
8+
trt_var <- strategy$trt_var
99

1010
# centre covariates
1111
centre_vars <- get_eff_mod_names(strategy$formula)
@@ -19,8 +19,8 @@ calc_stc <- function(strategy, ipd, ...) {
1919
# extract model coefficients
2020
coef_fit <- coef(fit)
2121

22-
# safer than treat_nm in case of factor level append
23-
treat_coef_name <- grep(paste0("^", treat_nm), names(coef_fit), value = TRUE)
22+
# safer than trt_var in case of factor level append
23+
treat_coef_name <- grep(paste0("^", trt_var, "[^:]*$"), names(coef_fit), value = TRUE)
2424

2525
# probability for control and treatment group
2626
# estimating treatment effect at means because of centring

R/gcomp_ml.R

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@
2323
gcomp_ml.boot <- function(data, indices,
2424
R, formula = NULL,
2525
family, trt_var,
26+
ref_trt = "C", comp_trt = "A",
2627
rho = NA,
2728
N = 1000, ald) {
2829
dat <- data[indices, ]
29-
gcomp_ml_means(formula, family, dat, ald, trt_var, rho, N)
30+
gcomp_ml_means(formula, family, dat, ald, trt_var, rho, N,
31+
ref_trt, comp_trt)
3032
}
3133

3234

@@ -62,7 +64,9 @@ gcomp_ml_means <- function(formula,
6264
ipd, ald,
6365
trt_var,
6466
rho = NA,
65-
N = 1000) {
67+
N = 1000,
68+
ref_trt = "C",
69+
comp_trt = "A") {
6670

6771
x_star <- simulate_ALD_pseudo_pop(formula = formula,
6872
ipd = ipd, ald = ald,
@@ -75,19 +79,19 @@ gcomp_ml_means <- function(formula,
7579
data = ipd)
7680

7781
# counterfactual datasets
78-
data.trtA <- data.trtC <- x_star
82+
data.comp <- data.ref <- x_star
7983

8084
# intervene on treatment while keeping set covariates fixed
81-
data.trtA[[trt_var]] <- 0 # all receive A
82-
data.trtC[[trt_var]] <- 1 # all receive C
85+
data.comp[[trt_var]] <- comp_trt # all receive A
86+
data.ref[[trt_var]] <- ref_trt # all receive C
8387

8488
# predict counterfactual event probs, conditional on treatment/covariates
85-
hat.mu.A <- predict(fit, type="response", newdata=data.trtA)
86-
hat.mu.C <- predict(fit, type="response", newdata=data.trtC)
89+
hat.mu.comp <- predict(fit, type="response", newdata=data.comp)
90+
hat.mu.ref <- predict(fit, type="response", newdata=data.ref)
8791

8892
# (marginal) mean probability prediction under A and C
89-
c(`0` = mean(hat.mu.A),
90-
`1` = mean(hat.mu.C))
93+
c(`0` = mean(hat.mu.ref),
94+
`1` = mean(hat.mu.comp))
9195
}
9296

9397

R/gcomp_stan.R

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
#' @export
3838
#'
3939
calc_gcomp_stan <- function(strategy,
40-
ipd, ald, ...) {
40+
ipd, ald,
41+
ref_trt = "C",
42+
comp_trt = "A", ...) {
4143

4244
formula <- strategy$formula
4345
family <- strategy$family
@@ -56,21 +58,21 @@ calc_gcomp_stan <- function(strategy,
5658
...)
5759

5860
# counterfactual datasets
59-
data.trtA <- data.trtC <- x_star
61+
data.comp <- data.ref <- x_star
6062

6163
# intervene on treatment while keeping set covariates fixed
62-
data.trtA[[trt_var]] <- 1 # everyone receives treatment A
63-
data.trtC[[trt_var]] <- 0 # receive treatment C
64+
data.comp[[trt_var]] <- comp_trt # all receive treatment A
65+
data.ref[[trt_var]] <- ref_trt # all receive treatment C
6466

6567
##TODO: is this going to work for all of the different data types?
6668
# draw responses from posterior predictive distribution
67-
y.star.A <- rstanarm::posterior_predict(outcome.model, newdata = data.trtA)
68-
y.star.C <- rstanarm::posterior_predict(outcome.model, newdata = data.trtC)
69+
y.star.comp <- rstanarm::posterior_predict(outcome.model, newdata = data.comp)
70+
y.star.ref <- rstanarm::posterior_predict(outcome.model, newdata = data.ref)
6971

7072
# posterior means for each treatment group
7173
list(
72-
mean_A = rowMeans(y.star.A),
73-
mean_C = rowMeans(y.star.C))
74+
mean_A = rowMeans(y.star.comp),
75+
mean_C = rowMeans(y.star.ref))
7476
}
7577

7678

@@ -116,6 +118,8 @@ calc_gcomp_ml <- function(strategy,
116118
formula = strategy$formula,
117119
family = strategy$family,
118120
trt_var = strategy$trt_var,
121+
ref_trt = "C",
122+
comp_trt = "A",
119123
rho = strategy$rho,
120124
N = strategy$N,
121125
data = ipd,

R/get_study_treatments.R

Lines changed: 0 additions & 13 deletions
This file was deleted.

R/mim.R

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#' @keywords internal
1010
#'
1111
calc_mim <- function(strategy,
12-
ipd, ald, ...) {
12+
ipd, ald,
13+
ref_trt = "C",
14+
comp_trt = "A", ...) {
1315

1416
formula <- strategy$formula
1517
family <- strategy$family
@@ -29,11 +31,15 @@ calc_mim <- function(strategy,
2931
algorithm = "sampling", ...)
3032

3133
# create augmented target dataset
32-
target.t1 <- target.t0 <- x_star
33-
target.t1$trt_var <- 1
34-
target.t0$trt_var <- 0
34+
target.comp <- target.ref <- x_star
35+
target.comp[[trt_var]] <- comp_trt
36+
target.ref[[trt_var]] <- ref_trt
3537

36-
aug.target <- rbind(target.t0, target.t1)
38+
aug.target <- rbind(target.ref, target.comp)
39+
40+
# set reference treatment as base level
41+
aug.target[[trt_var]] <- factor(aug.target[[trt_var]],
42+
levels = c(ref_trt, comp_trt))
3743

3844
# complete syntheses by drawing binary outcomes
3945
# from their posterior predictive distribution
@@ -52,18 +58,21 @@ calc_mim <- function(strategy,
5258
glm(as.formula(paste("y ~", trt_var)), data = data_m, family = family)
5359
})
5460

55-
5661
# treatment effect point estimates in each synthesis
5762
coef_fit <- do.call(rbind, lapply(reg2.fits, function(fit) coef(fit)))
5863

64+
# safer than trt_var in case of factor level append
65+
coef_names <- names(coef(reg2.fits[[1]]))
66+
treat_coef_name <- grep(pattern = paste0("^", trt_var, "[^:]*$"), coef_names, value = TRUE)
67+
5968
##TODO: how to transform this to the prob scale?
6069
# point estimates for the variance in each synthesis
6170
hats.v <- unlist(lapply(reg2.fits,
6271
function(fit)
63-
vcov(fit)[trt_var, trt_var]))
72+
vcov(fit)[treat_coef_name, treat_coef_name]))
6473

65-
mean_C <- family$linkinv(coef_fit[, 1]) # probability for control
66-
mean_A <- family$linkinv(coef_fit[, 1] + coef_fit[, 2]) # probability for treatment
74+
mean_C <- family$linkinv(coef_fit[, 1]) # probability for reference
75+
mean_A <- family$linkinv(coef_fit[, 1] + coef_fit[, treat_coef_name]) # probability for comparator
6776

6877
tibble::lst(mean_A, mean_C,
6978
hats.v, M)

R/outstandR.R

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,18 @@
66
#' Methods taken from
77
#' \insertCite{RemiroAzocar2022}{outstandR}.
88
#'
9-
#' @param ipd_trial Individual-level patient data. Suppose between studies _A_ and _C_.
10-
#' @param ald_trial Aggregate-level data. Suppose between studies _B_ and _C_.
9+
#' @param ipd_trial Individual-level patient data. For example, suppose between studies _A_ and _C_.
10+
#' In a long format and must contain a treatment column and outcome column consistent with the formula object.
11+
#' The labels in the treatment are used internally so there must be a common treatment with the aggregate-level data trial.
12+
#' @param ald_trial Aggregate-level data. For example, suppose between studies _B_ and _C_. The column names take the form
13+
#' - `mean.X*`: mean patient measurement
14+
#' - `sd.X*`: standard deviation of patient measurement
15+
#' - `y.*.sum`: total number of events
16+
#' - `y.*.bar`: proportion of events
17+
#' - `N.*`: total number of individuals
1118
#' @param strategy Computation strategy function. These can be
1219
#' `strategy_maic()`, `strategy_stc()`, `strategy_gcomp_ml()` and `strategy_gcomp_stan()`
20+
#' @param ref_trt Reference / common / anchoring treatment name; default "C"
1321
#' @param CI Confidence interval; between 0,1
1422
#' @param scale Relative treatment effect scale. If `NULL`, the scale is automatically determined from the model.
1523
#' @param ... Additional arguments
@@ -27,44 +35,63 @@
2735
#' data(AC_IPD) # AC patient-level data
2836
#' data(BC_ALD) # BC aggregate-level data
2937
#'
38+
#' # linear formula
3039
#' lin_form <- as.formula("y ~ X3 + X4 + trt*X1 + trt*X2")
3140
#'
3241
#' # matching-adjusted indirect comparison
33-
#' outstandR_maic <- outstandR(AC_IPD, BC_ALD, strategy = strategy_maic(formula = lin_form))
42+
#' outstandR_maic <- outstandR(AC_IPD, BC_ALD,
43+
#' strategy = strategy_maic(formula = lin_form))
3444
#'
3545
#' # simulated treatment comparison
36-
#' outstandR_stc <- outstandR(AC_IPD, BC_ALD, strategy = strategy_stc(lin_form))
46+
#' outstandR_stc <- outstandR(AC_IPD, BC_ALD,
47+
#' strategy = strategy_stc(lin_form))
3748
#'
3849
#' # G-computation with maximum likelihood
39-
#' # outstandR_gcomp_ml <- outstandR(AC_IPD, BC_ALD, strategy = strategy_gcomp_ml(lin_form))
50+
#' # outstandR_gcomp_ml <- outstandR(AC_IPD, BC_ALD,
51+
#' strategy = strategy_gcomp_ml(lin_form))
4052
#'
4153
#' # G-computation with Bayesian inference
42-
#' outstandR_gcomp_stan <- outstandR(AC_IPD, BC_ALD, strategy = strategy_gcomp_stan(lin_form))
54+
#' outstandR_gcomp_stan <- outstandR(AC_IPD, BC_ALD,
55+
#' strategy = strategy_gcomp_stan(lin_form))
4356
#'
4457
#' # Multiple imputation marginalization
45-
#' outstandR_gcomp_stan <- outstandR(AC_IPD, BC_ALD, strategy = strategy_mim(lin_form))
58+
#' outstandR_mim <- outstandR(AC_IPD, BC_ALD,
59+
#' strategy = strategy_mim(lin_form))
4660
#'
47-
outstandR <- function(ipd_trial, ald_trial, ref_trt = "C",
48-
strategy, CI = 0.95, scale = NULL, ...) {
61+
outstandR <- function(ipd_trial, ald_trial, strategy,
62+
ref_trt = "C",
63+
CI = 0.95, scale = NULL, ...) {
4964

5065
validate_outstandr(ipd_trial, ald_trial, strategy, CI, scale)
5166

5267
ipd <- prep_ipd(strategy$formula, ipd_trial)
5368
ald <- prep_ald(strategy$formula, ald_trial, trt_var = strategy$trt_var)
5469

55-
ipd_trts <- get_ipd_trts(ipd, ref_trt)
56-
ald_trts <- get_ald_trts(ald, ref_trt)
70+
# treatment names for each study
71+
72+
ipd_comp <- get_ipd_comparator(ipd, ref_trt, strategy$trt_var)
73+
ald_comp <- get_ald_comparator(ald, ref_trt)
74+
75+
ipd_trts <- list(ipd_comp, ref_trt)
76+
ald_trts <- list(ald_comp, ref_trt)
5777

5878
if (is.null(scale)) scale <- get_treatment_effect(strategy$family$link)
5979

60-
ipd_stats <- calc_IPD_stats(strategy, ipd = ipd, ald = ald, scale, ...)
61-
ald_stats <- calc_ALD_stats(strategy, ald = ald, treatments = ald_trts, scale = scale)
80+
ipd_stats <- calc_IPD_stats(strategy,
81+
ipd = ipd, ald = ald,
82+
scale, ...)
83+
84+
ald_stats <- calc_ALD_stats(strategy, ald = ald,
85+
treatments = ald_trts,
86+
scale = scale)
6287

6388
stats <- result_stats(ipd_stats, ald_stats, CI)
6489

65-
structure(stats,
66-
CI = CI,
67-
scale = scale,
68-
model = strategy$family$family,
69-
class = c("outstandR", class(stats)))
90+
structure(
91+
stats,
92+
CI = CI,
93+
ref_trt = ref_trt,
94+
scale = scale,
95+
model = strategy$family$family,
96+
class = c("outstandR", class(stats)))
7097
}

R/prep_data.R

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ prep_ald <- function(form, data, trt_var = "trt") {
3939

4040
#' Convert from long to wide format
4141
#'
42-
#' @import plyr
4342
#' @import tidyr
4443
#' @import stringr
4544
#'
@@ -75,3 +74,25 @@ reshape_ald_to_wide <- function(df) {
7574

7675
bind_cols(variable_df, y_df)
7776
}
77+
78+
# Get study comparator treatment names
79+
80+
#
81+
get_ald_comparator <- function(ald, ref_trt = "C") {
82+
83+
pattern <- paste0("^y\\.(?!", ref_trt, ")")
84+
85+
# filter for names starting with "y." but not with "y.C"
86+
y_non_ref <- grep(pattern, colnames(ald),
87+
value = TRUE, perl = TRUE)
88+
89+
# extract treatment of first match
90+
sub("^y\\.([A-Z]).*", "\\1", y_non_ref[1])
91+
}
92+
93+
#
94+
get_ipd_comparator <- function(ipd, ref_trt = "C", trt_var = "trt") {
95+
all_trt <- levels(ipd[[trt_var]])
96+
all_trt[all_trt != ref_trt]
97+
}
98+

R/print.R

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ print.outstandR <- function(x, ...) {
1414
stop("Please install the 'tibble' and 'pillar' packages for colored tibble output.")
1515
}
1616

17+
ref_trt <- attr(x, "ref_trt")
18+
1719
cat(pillar::style_bold("Object of class 'outstandR'"), "\n")
1820
cat("Model:", pillar::style_subtle(attr(x, "model")), "\n")
1921
cat("Scale:", pillar::style_subtle(attr(x, "scale")), "\n")
20-
cat("Common treatment:", pillar::style_subtle("C"), "\n")
22+
cat("Common treatment:", pillar::style_subtle(ref_trt), "\n")
2123
# cat(pillar::style_subtle("Common treatment:"), attr(x, "reference"), "\n") ##TODO:
2224
cat("Individual patient data study:", pillar::style_subtle("AC"), "\n")
2325
cat("Aggregate level data study:", pillar::style_subtle("BC"), "\n")
@@ -46,8 +48,8 @@ print.outstandR <- function(x, ...) {
4648
Treatments = names(absolute$means),
4749
Estimate = unlist(absolute$means),
4850
Std.Error = unlist(absolute$variances),
49-
lower.0.95 = sapply(absolute$CI, \(x) x[1]),
50-
upper.0.95 = sapply(absolute$CI, \(x) x[2])
51+
lower.0.95 = c(NA,NA), #sapply(absolute$CI, \(x) x[1]), ##TODO:
52+
upper.0.95 = c(NA,NA) #sapply(absolute$CI, \(x) x[2])
5153
)
5254

5355
cat("Contrasts:\n\n")

0 commit comments

Comments
 (0)