For a current set of projects, I use a single set of aggregate Stan models, in the vein of the “eight schools example.” The models take as data one or more treatment estimates from one or more RCTs at different partner sites, never student-level data. Treatment estimates come from frequentist models in which the functional form depends on the outcome (e.g. Poisson model for number of days absent, linear models for test score outcomes, etc.). Because the functional form can differ for what gets passed in to Stan, I want to specify generated quantities that are conditional on that functional form.
For example, Poisson treatment estimates get passed to the model untransformed, so in generated quantities I would like to perform the typical transformation to get percent change: exp(\beta)-1. But of course if estimates passed in come from a linear model, this generated quantity isn’t needed.
From the Stan reference manual section 5.3, I know of “Declaring Optional Variables,” which is the basis of my solution below. Though I’d really love to be able to conditionally generate bt_trans as a real type, not a vector, because that’s all I really need. Is that not possible? Previous posts left this unclear to me. Any new insights are much appreciated.
(This model for a single estimate from a single partner site is to illustrate my question. For multiple partner sites running multiple treatment arms, the model is more complex, so that we can partially pool across sites. In such scenarios, there are many more generated quantities of interest, all of which again differ depending on the functional form of the frequentist model used to estimate treatment effects.)
data {
// Number of partner sites
int<lower=1> P; // Just set to 1 in this case
// Treatment estimate
real y;
// Standard error of estimate
real<lower=0> sigma;
// Prior on sd of treatment effect
real<lower=0> prior_full_sd;
// Prior mean on overall treatment effect
real prior_mu;
// Poisson functional form
int<lower=0,upper=1> Poisson;
}
transformed data {
real<lower=0> bt_prior_sd;
// Prior on the overall
bt_prior_sd = prior_full_sd;
}
parameters {
// Overall effect
real bt;
}
model {
// Prior on overall effect
bt ~ normal(prior_mu, bt_prior_sd);
// Model
y ~ normal(bt, sigma);
}
generated quantities {
// Poisson estimate transformed to give percent change
vector[Poisson ? 1 : 0] bt_trans;
if (Poisson==1) {
bt_trans[1] = exp(bt)-1;
}
}