Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Informative prior archetypes #100

Merged
merged 84 commits into from
May 29, 2024
Merged

Informative prior archetypes #100

merged 84 commits into from
May 29, 2024

Conversation

wlandau
Copy link
Collaborator

@wlandau wlandau commented May 2, 2024

This pull request lays the groundwork for informative prior archetypes. It fixes #96 and #99, and adds a citation for https://opensource.nibr.com/bamdd/src/02h_mmrm.html.

@andrew-bean, @chstock, and @yonicd, would you please have a look? The new vignettes/archetypes.Rmd vignette has the key features.

@wlandau
Copy link
Collaborator Author

wlandau commented May 16, 2024

@yonicd, I added archetypes to parameterize the average across time within each treatment group. Using the FEV data:

library(brms.mmrm)
library(dplyr)
data("fev_data", package = "mmrm")
data <- brm_data(
  data = fev_data,
  outcome = "FEV1",
  role = "response",
  group = "ARMCD",
  time = "AVISIT",
  reference_group = "PBO",
  reference_time = "VIS1"
)

brm_archetype_average_cells() is the cell means version. Below, x_PBO_VIS1 is actually the average across time for PBO, and x_TRT_VIS1 is the same for TRT. The labels still include "VIS1" so the labeling scheme remains consistent from archetype to archetype and brm_prior_label()/brm_prior_archetype() can still set informative priors.

cells <- brm_archetype_average_cells(data)
summary(cells)
# This object is an informative prior archetype in brms.mmrm.
# The fixed effect parameters of interest express the
# marginal means as follows (on the link scale):
# 
#    PBO:VIS1 = 4*x_PBO_VIS1 - x_PBO_VIS2 - x_PBO_VIS3 - x_PBO_VIS4
#    PBO:VIS2 = x_PBO_VIS2
#    PBO:VIS3 = x_PBO_VIS3
#    PBO:VIS4 = x_PBO_VIS4
#    TRT:VIS1 = 4*x_TRT_VIS1 - x_TRT_VIS2 - x_TRT_VIS3 - x_TRT_VIS4
#    TRT:VIS2 = x_TRT_VIS2
#    TRT:VIS3 = x_TRT_VIS3
#    TRT:VIS4 = x_TRT_VIS4

Above, (PBO:VIS1 + PBO:VIS2 + PBO:VIS3 + PBO:VIS4) / 4 simplifies to x_PBO_VIS1, and (TRT:VIS1 + TRT:VIS2 + TRT:VIS3 + TRT:VIS4) / 4 simplifies to x_TRT_VIS1.

I also threw in a treatment effect version:

effects <- brm_archetype_average_effects(data)
summary(effects)
# This object is an informative prior archetype in brms.mmrm.
# The fixed effect parameters of interest express the
# marginal means as follows (on the link scale):
# 
#    PBO:VIS1 = 4*x_PBO_VIS1 - x_PBO_VIS2 - x_PBO_VIS3 - x_PBO_VIS4
#    PBO:VIS2 = x_PBO_VIS2
#    PBO:VIS3 = x_PBO_VIS3
#    PBO:VIS4 = x_PBO_VIS4
#    TRT:VIS1 = 4*x_PBO_VIS1 - x_PBO_VIS2 - x_PBO_VIS3 - x_PBO_VIS4 + 4*x_TRT_VIS1 - x_TRT_VIS2 - x_TRT_VIS3 - x_TRT_VIS4
#    TRT:VIS2 = x_PBO_VIS2 + x_TRT_VIS2
#    TRT:VIS3 = x_PBO_VIS3 + x_TRT_VIS3
#    TRT:VIS4 = x_PBO_VIS4 + x_TRT_VIS4

Above, x_PBO_VIS1 is still the average placebo response over all time points, but now x_TRT_VIS1 is the average treatment effect. In other words, x_TRT_VIS1 is the result of (TRT:VIS1 + TRT:VIS2 + TRT:VIS3 + TRT:VIS4) / 4 - (PBO:VIS1 + PBO:VIS2 + PBO:VIS3 + PBO:VIS4) / 4.

This brings us up to 6 different archetypes:

  • brm_archetype_average_cells()
  • brm_archetype_average_effects()
  • brm_archetype_cells()
  • brm_archetype_effects()
  • brm_archetype_successive_cells()
  • brm_archetype_successive_effects()

I believe this completes this PR, unless others have comments (please let me know). Archetypes are cheap, and it is easy for me to add more.

@wlandau
Copy link
Collaborator Author

wlandau commented May 16, 2024

I also added a section to vignettes/archetypes.Rmd to explain the other archetypes.

Copy link
Collaborator

@chstock chstock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new functions seem very useful and the vignette describes their use very clearly - it will definitely be helpful for users. I didn't spot any potential major issues.

One thing I kept thinking about: we regularly use MMRMs with baseline:time and treatment:time interactions. Elicitation seems to be more challenging then (due to the second interaction). Which archetype would I use, or how would a I construct a suitable one? Apologies if this is already covered and I missed it.

vignettes/archetypes.Rmd Outdated Show resolved Hide resolved
vignettes/archetypes.Rmd Outdated Show resolved Hide resolved
vignettes/archetypes.Rmd Show resolved Hide resolved
@wlandau
Copy link
Collaborator Author

wlandau commented May 20, 2024

One thing I kept thinking about: we regularly use MMRMs with baseline:time and treatment:time interactions. Elicitation seems to be more challenging then (due to the second interaction). Which archetype would I use, or how would a I construct a suitable one? Apologies if this is already covered and I missed it.

Is there usually a reason to set informative priors on baseline:time interactions? I would think these are nuisance parameters and solely used to explain noise. The current approach in the archetype interface is to manually compute the model matrix columns for these interactions and center them at their means. (Centering protects the interpretation of the parameters of interest against subtle reference level issues like the one from #24 (comment).)

As for treatment:time, the three current *_cells() archetypes implicitly cover treatment:time interactions in different ways, but only in a simplified context where the precise meaning of each parameter is clear. There is currently no archetype for intercept + treatment + time + treatment:time, and I think it may be hard for users because the precise meaning of treatment:time depends on how the contrasts drop model matrix columns and which combination of levels is chosen as the reference level. For example, it's a bit hard to think of what an informative prior should be for treatment2:time2 when this parameter is defined relative to intercept + time2 + treatment2, and even this needs to take into account whether time1/treatment1 or time_N/treatment_N is dropped from the model matrix.

@chstock
Copy link
Collaborator

chstock commented May 21, 2024

One thing I kept thinking about: we regularly use MMRMs with baseline:time and treatment:time interactions. Elicitation seems to be more challenging then (due to the second interaction). Which archetype would I use, or how would a I construct a suitable one? Apologies if this is already covered and I missed it.

Is there usually a reason to set informative priors on baseline:time interactions? I would think these are nuisance parameters and solely used to explain noise. The current approach in the archetype interface is to manually compute the model matrix columns for these interactions and center them at their means. (Centering protects the interpretation of the parameters of interest against subtle reference level issues like the one from #24 (comment).)

As for treatment:time, the three current *_cells() archetypes implicitly cover treatment:time interactions in different ways, but only in a simplified context where the precise meaning of each parameter is clear. There is currently no archetype for intercept + treatment + time + treatment:time, and I think it may be hard for users because the precise meaning of treatment:time depends on how the contrasts drop model matrix columns and which combination of levels is chosen as the reference level. For example, it's a bit hard to think of what an informative prior should be for treatment2:time2 when this parameter is defined relative to intercept + time2 + treatment2, and even this needs to take into account whether time1/treatment1 or time_N/treatment_N is dropped from the model matrix.

Thanks, I can see how this would complicate things. In some situations, in my experience, baseline has been essentially the only known or the strongest prognostic variable (it often seems to correlate strongly with other (un)observered prognostic variables). So it often has a special role among the nuisance variable, I believe. Evidence might exist from natural history studies or (more frequently and increasingly) from historical trial data to which MMRMs with baseline x time interactions had been fit. Fully fine if we do not address this at the moment.

@wlandau
Copy link
Collaborator Author

wlandau commented May 22, 2024

You do make a good case for borrowing information on baseline:time interactions in some circumstances. And since these parameters are time-specific slopes, the centering I described above should not interfere with interpretation or priors. (brms.mmrm does not scale these columns of the model matrix.)

Using brms::set_prior(), it is possible to assign informative priors on the other parameters in the model, including baseline:time interactions. The only extra challenge at the user level is identifying the names of those parameters, possibly using a manual call to brms::get_prior(). This should already work smoothly for highly customized/specialized analyses. My question is whether it is worth extending brms.mmrm::brm_prior_label() etc. to make it extra convenient to set priors. This would require a challenging redesign at both the interface and infrastructure levels.

@chstock
Copy link
Collaborator

chstock commented May 23, 2024

My question is whether it is worth extending brms.mmrm::brm_prior_label() etc. to make it extra convenient to set priors. This would require a challenging redesign at both the interface and infrastructure levels.

I'd be fine if we wait and see whether substantial demand for such custom priors comes up. Maybe the case with the baseline:time interaction could be handled in an additional vignette. I could take this on, if that is ok for you. We can also discuss this in one of the next meetings.

@wlandau
Copy link
Collaborator Author

wlandau commented May 24, 2024

Maybe the case with the baseline:time interaction could be handled in an additional vignette.

a7b9126 adds this to the "Informative priors" section of the existing archetypes.Rmd vignette.

I could take this on, if that is ok for you. We can also discuss this in one of the next meetings.

Thanks, it would be great to discuss.

archetypes.Rmd is very software-focused. It accomplishes its goals as a software usage tutorial, but it uses simulated data, and the priors have no justification. It may help to complement this with a realistic case study in a different vignette which uses an archetype with a clinically meaningful set of informative priors.

@wlandau wlandau merged commit 5200daa into main May 29, 2024
3 of 15 checks passed
@wlandau wlandau deleted the 96 branch May 29, 2024 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Alternative modeling workflows for specific parameterizations and informative prior cases
2 participants