Skip to content

Commit

Permalink
Start #119
Browse files Browse the repository at this point in the history
  • Loading branch information
wlandau committed Jul 11, 2024
1 parent 4ef4108 commit 66b5e33
Show file tree
Hide file tree
Showing 33 changed files with 110 additions and 147 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: brms.mmrm
Title: Bayesian MMRMs using 'brms'
Version: 1.0.1.9006
Version: 1.0.1.9007
Authors@R: c(
person(
given = c("William", "Michael"),
Expand Down
3 changes: 2 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# brms.mmrm 1.0.1.9006 (development)
# brms.mmrm 1.0.1.9007 (development)

* Add `brm_marginal_grid()`.
* Show posterior samples of `sigma` in `brm_marginal_draws()` and `brm_marginal_summaries()`.
Expand All @@ -10,6 +10,7 @@
* Take defaults `data` and `formula` from the above in `brm_marginal_draws()`.
* Set the default value of `effect_size` to `attr(formula, "brm_allow_effect_size")`.
* Remove defaults from some arguments to `brm_data()` and document examples.
* Deprecate the `role` argument of `brm_data()` in favor of `reference_time` (#119).

# brms.mmrm 1.0.1

Expand Down
2 changes: 1 addition & 1 deletion R/brm_archetype_successive_cells.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#'
#' For group A, `beta_1` is the time 1 intercept, `beta_2` represents
#' time 2 minus time 1, and `beta_3` represents time 3 minus time 2.
#' `beta_4`, `beta_5`, and `beta_6` represent the analogous roles.
#' `beta_4`, `beta_5`, and `beta_6` behave analogously for group B.
#' @section Nuisance variables:
#' In the presence of covariate adjustment, functions like
#' [brm_archetype_successive_cells()] convert nuisance factors into binary
Expand Down
45 changes: 19 additions & 26 deletions R/brm_data.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
#' Example possibilities from clinical trial datasets include
#' `"CHG"` and `"AVAL"`.
#' The `outcome` column in the data should be a numeric vector.
#' @param role Character of length 1. Either `"response"` if `outcome`
#' is the raw response variable (e.g. AVAL) or `"change"` if `outcome`
#' is change from baseline (e.g. CHG).
#' @param baseline Character of length 1,
#' name of the baseline response variable (for example, `"BASE"`
#' in many clinical trial datasets).
Expand Down Expand Up @@ -91,17 +88,22 @@
#' model matrix that `brms` derives from the formula from `brm_formula()`.
#' @param reference_time Atomic value of length 1 or `NULL`,
#' level of the `time` column to indicate the baseline time point.
#' This value must be `NULL` if the outcome
#' variable is already change from baseline. If the outcome
#' is raw response, then `reference_time` may or may not be `NULL`.
#' [brm_marginal_draws()] and downstream functions calculate posterior
#' inference on change from baseline if and only if
#' `reference_time` is not `NULL`.
#' Leave as `NULL` if there is no baseline or baseline is not included
#' in `data[[time]]`.
#'
#' If `reference_time` is not `NULL`, then [brm_marginal_draws()] will
#' calculate change from baseline, and it will calculate treatment
#' differences as differences between change-from-baseline values.
#' If `reference_time` is not `NULL`, then [brm_marginal_draws()] will
#' not calculate change from baseline, and it will calculate treatment
#' differences as differences between response values.
#'
#' Note: `reference_time` only applies to the post-processing that happens
#' in functions like [brm_marginal_draws()] downstream of the model.
#' It does not control the fixed effect mapping in the
#' model matrix that `brms` derives from the formula from `brm_formula()`.
#' @param role Deprecated as unnecessary on 2024-07-11 (version 1.0.1.9007).
#' Use `reference_time` to supply a baseline time point value if it exists.
#' @param level_baseline Deprecated on 2024-01-11 (version 0.2.0.9002).
#' Use `reference_time` instead.
#' @param level_control Deprecated on 2024-01-11 (version 0.2.0.9002).
Expand All @@ -114,7 +116,6 @@
#' brm_data(
#' data = data,
#' outcome = "col_response",
#' role = "response",
#' group = "col_group",
#' time = "col_time",
#' patient = "col_patient",
Expand All @@ -124,7 +125,6 @@
brm_data <- function(
data,
outcome,
role = "change",
baseline = NULL,
group,
subgroup = NULL,
Expand All @@ -135,10 +135,18 @@ brm_data <- function(
reference_group,
reference_subgroup = NULL,
reference_time = NULL,
role = NULL,
level_baseline = NULL,
level_control = NULL
) {
assert(is.data.frame(data), message = "data arg must be a data frame.")
if (!is.null(role)) {
brm_deprecate(
"The 'role' argument was deprecated as unnecessary on 2024-07-11 ",
"(version 1.0.1.9007). Use reference_time to specify a baseline ",
"time value if it exists."
)
}
if (!is.null(level_control)) {
brm_deprecate(
"level_control was deprecated on 2024-01-11 (version 0.2.0.9002). ",
Expand All @@ -158,7 +166,6 @@ brm_data <- function(
out <- brm_data_new(
data = data,
brm_outcome = as.character(outcome),
brm_role = as.character(role),
brm_baseline = baseline,
brm_group = as.character(group),
brm_subgroup = subgroup,
Expand All @@ -177,7 +184,6 @@ brm_data <- function(
brm_data_new <- function(
data,
brm_outcome = NULL,
brm_role = NULL,
brm_baseline = NULL,
brm_group = NULL,
brm_subgroup = NULL,
Expand All @@ -193,7 +199,6 @@ brm_data_new <- function(
structure(
out,
brm_outcome = brm_outcome,
brm_role = brm_role,
brm_baseline = brm_baseline,
brm_group = brm_group,
brm_subgroup = brm_subgroup,
Expand All @@ -220,7 +225,6 @@ brm_data_validate <- function(data) {
#' @export
brm_data_validate.default <- function(data) {
outcome <- attr(data, "brm_outcome")
role <- attr(data, "brm_role")
baseline <- attr(data, "brm_baseline")
group <- attr(data, "brm_group")
subgroup <- attr(data, "brm_subgroup")
Expand All @@ -237,7 +241,6 @@ brm_data_validate.default <- function(data) {
message = "please use brm_data() to preprocess your data"
)
assert_chr(outcome, "outcome of data must be a nonempty character string")
assert_chr(role, "role of data must be a nonempty character string")
assert_chr(
baseline %|||% "x",
"baseline must NULL or a nonempty character string"
Expand Down Expand Up @@ -266,10 +269,6 @@ brm_data_validate.default <- function(data) {
"in the data"
)
)
assert(
role %in% c("response", "change"),
message = "role must be either \"response\" or \"change\""
)
assert_col(outcome, data)
assert_col(baseline, data)
assert_col(group, data)
Expand Down Expand Up @@ -369,12 +368,6 @@ brm_data_validate.default <- function(data) {
)
)
}
if (role == "change") {
assert(
is.null(reference_time),
message = "reference_time must be NULL if role is \"change\"."
)
}
}

brm_data_fill <- function(data) {
Expand Down
14 changes: 5 additions & 9 deletions R/brm_data_change.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
#' change from baseline will be missing if either the post-baseline response
#' is missing or the baseline response is missing.
#' @param data A classed `tibble` (e.g. from [brm_data()]) with raw response
#' as the outcome variable (role = `"response"` in [brm_data()]).
#' as the outcome variable and no baseline time point stored in the
#' attributes.
#' @param name_change Character of length 1, name of the new outcome column
#' for change from baseline.
#' @param name_baseline Character of length 1, name of the new column for
Expand All @@ -24,21 +25,18 @@
#' data <- brm_data(
#' data = dplyr::rename(brm_simulate_simple()$data, y_values = response),
#' outcome = "y_values",
#' role = "response",
#' group = "group",
#' time = "time",
#' patient = "patient",
#' reference_group = "group_1",
#' reference_time = "time_1"
#' )
#' data
#' attr(data, "brm_role")
#' attr(data, "brm_outcome")
#' attr(data, "brm_baseline")
#' attr(data, "brm_reference_time")
#' changed <- brm_data_change(data = data, name_change = "delta")
#' changed
#' attr(changed, "brm_role")
#' attr(changed, "brm_outcome")
#' attr(changed, "brm_baseline")
#' attr(data, "brm_reference_time")
Expand All @@ -55,11 +53,10 @@ brm_data_change <- function(
)
)
assert(
attr(data, "brm_role") == "response",
!is.null(attr(data, "brm_reference_time")),
message = paste(
"outcome variable must be raw response",
"(not change from baseline)",
"in the data supplied to brm_data_change()."
"In brm_data_change(), a baseline time point needs to exist.",
"It needs to have already been specified through brm_data()."
)
)
assert_chr(name_change)
Expand Down Expand Up @@ -101,7 +98,6 @@ brm_data_change <- function(
brm_data(
data = out,
outcome = name_change,
role = "change",
baseline = name_baseline,
group = attr(data, "brm_group"),
subgroup = attr(data, "brm_subgroup"),
Expand Down
2 changes: 0 additions & 2 deletions R/brm_formula.R
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@
#' data <- brm_data(
#' data = brm_simulate_simple()$data,
#' outcome = "response",
#' role = "response",
#' group = "group",
#' time = "time",
#' patient = "patient",
Expand Down Expand Up @@ -371,7 +370,6 @@ brm_formula.default <- function(
brm_formula_validate_correlation(correlation)
brm_formula_sigma_validate(sigma)
name_outcome <- attr(data, "brm_outcome")
name_role <- attr(data, "brm_role")
name_baseline <- attr(data, "brm_baseline")
name_group <- attr(data, "brm_group")
name_subgroup <- attr(data, "brm_subgroup")
Expand Down
2 changes: 0 additions & 2 deletions R/brm_formula_sigma.R
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
#' data <- brm_data(
#' data = brm_simulate_simple()$data,
#' outcome = "response",
#' role = "response",
#' group = "group",
#' time = "time",
#' patient = "patient",
Expand Down Expand Up @@ -150,7 +149,6 @@ brm_formula_sigma <- function(
baseline_time ||
covariates
allow_effect_size <- !exclude_effect_size
name_role <- attr(data, "brm_role")
name_baseline <- attr(data, "brm_baseline")
name_group <- attr(data, "brm_group")
name_subgroup <- attr(data, "brm_subgroup")
Expand Down
1 change: 0 additions & 1 deletion R/brm_marginal_data.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
#' data <- brm_data(
#' data = brm_simulate_simple()$data,
#' outcome = "response",
#' role = "response",
#' group = "group",
#' time = "time",
#' patient = "patient",
Expand Down
42 changes: 28 additions & 14 deletions R/brm_marginal_draws.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
#' @export
#' @family marginals
#' @description Get marginal posterior draws from a fitted MMRM.
#' @section Baseline:
#' The returned values from [brm_marginal_draws()]
#' depend on whether a baseline time point
#' was declared through the `reference_time` argument of [brm_data()].
#' If `reference_time` was not `NULL`, then [brm_marginal_draws()] will
#' calculate change from baseline, and it will calculate treatment
#' differences as differences between change-from-baseline values.
#' If `reference_time` was not `NULL`, then [brm_marginal_draws()] will
#' not calculate change from baseline, and it will calculate treatment
#' differences as differences between response values.
#' @inheritSection brm_data Separation string
#' @return A named list of tibbles of MCMC draws of the marginal posterior
#' distribution of each treatment group and time point. These marginals
Expand All @@ -19,15 +29,21 @@
#' not `NULL` (i.e. if a baseline value for the time variable
#' was identified).
#' * `difference_group`: treatment effect:
#' the `difference_time` at each active group minus the `difference_time`
#' at the control group (`reference_group`).
#' If `reference_time` was `NULL` in [brm_data()] (i.e. no baseline
#' time point), then treatment group
#' is instead the difference between `response` at each active group minus
#' the `response` at the control group.
#' These samples depend on the values of `reference_group` and
#' `reference_time` which were originally declared in [brm_data()].
#' `reference_group` is the control group, and `reference_time`
#' is baseline. If baseline was originally given (via `reference_time`
#' in [brm_data()]),
#' then `difference_time` is the change-from-baseline value of
#' each active group minus that of the control group.
#' Otherwise, if baseline is omitted (i.e. `reference_time = NULL`
#' (default) in [brm_data()]), then `difference_time` is the
#' raw response at each active group minus that of the control group.
#' * `difference_subgroup`: subgroup differences: the `difference_group`
#' at each subgroup level minus the `difference_group` at the subgroup
#' reference level (`reference_subgroup`).
#' reference level (`reference_subgroup`). Only reported if a subgroup
#' analysis was specified through the appropriate arguments to
#' [brm_data()] and [brm_formula()].
#' * `effect`: effect size, defined as the treatment difference
#' divided by the residual standard deviation. Omitted if
#' the `effect_size` argument is `FALSE` or if the
Expand Down Expand Up @@ -71,7 +87,6 @@
#' data <- brm_data(
#' data = brm_simulate_simple()$data,
#' outcome = "response",
#' role = "response",
#' group = "group",
#' time = "time",
#' patient = "patient",
Expand Down Expand Up @@ -143,7 +158,6 @@ brm_marginal_draws <- function(
brm_data_validate(data)
brm_formula_validate(formula)
brm_model_validate(model)
role <- attr(data, "brm_role")
base <- attr(data, "brm_base")
group <- attr(data, "brm_group")
subgroup <- attr(data, "brm_subgroup")
Expand All @@ -161,7 +175,7 @@ brm_marginal_draws <- function(
reference_subgroup <- attr(data, "brm_reference_subgroup")
reference_time <- attr(data, "brm_reference_time")
has_subgroup <- brm_has_subgroup(data = data, formula = formula)
has_baseline <- identical(role, "response") && !is.null(reference_time)
has_baseline <- !is.null(reference_time)
if (effect_size && !attr(formula, "brm_allow_effect_size")) {
effect_size <- FALSE
brm_warn(
Expand Down Expand Up @@ -197,7 +211,7 @@ brm_marginal_draws <- function(
draws_response <- tibble::as_tibble(as.matrix(draws_beta) %*% t(transform))
draws_response <- dplyr::bind_cols(draws_response, index_mcmc)
draws_response <- posterior::as_draws_df(draws_response)
if (has_baseline) { # baseline
if (has_baseline) { # baseline exists, subgroup exists
if (has_subgroup) {
draws_difference_time <- subtract_reference_time_subroup(
draws = draws_response,
Expand All @@ -220,7 +234,7 @@ brm_marginal_draws <- function(
levels_time = setdiff(levels_time, reference_time),
reference_subgroup = reference_subgroup
)
} else { # role is "response", no subgroup
} else { # baseline exists, no subgroup
draws_difference_time <- subtract_reference_time(
draws = draws_response,
levels_group = levels_group,
Expand All @@ -234,7 +248,7 @@ brm_marginal_draws <- function(
reference_group = reference_group
)
}
} else { # baseline does not exist
} else { # baseline does not exist, subgroup exists
if (has_subgroup) {
draws_difference_group <- subtract_reference_group_subgroup(
draws = draws_response,
Expand All @@ -250,7 +264,7 @@ brm_marginal_draws <- function(
levels_time = levels_time,
reference_subgroup = reference_subgroup
)
} else { # role is "change", no subgroup
} else { # baseline does not exist, no subgroup
draws_difference_group <- subtract_reference_group(
draws = draws_response,
levels_group = levels_group,
Expand Down
Loading

0 comments on commit 66b5e33

Please sign in to comment.