I am creating an R Shiny web-app that would allow users to input a custom dataset, select analysis variables, and fit a Bayesian ANCOVA model using user-specified prior values. This is what the relevant code looks like: (server portion)
bfit <- eventReactive(
input$activate,
ignoreNULL = F,
{
req(lmmformula, anovaformula, ancovaformula, input$interceptMean,
input$interceptVariance, input$baselineMean, input$baselineVariance,
input$treatmentMean, input$treatmentVariance, input$sigmaScale,
input$seed)
stanparams <- stanvar(input$interceptMean, "intercept_mean") +
stanvar(sqrt(input$interceptVariance), "intercept_sd") +
stanvar(input$baselineMean, "baseline_mean") +
stanvar(sqrt(input$baselineVariance), "baseline_sd") +
stanvar(input$treatmentMean, "treatment_mean") +
stanvar(sqrt(input$treatmentVariance), "treatment_sd") +
stanvar(input$sigmaScale, "sigma_scale")
priors <- c(prior(normal(intercept_mean,
intercept_sd),
class = "Intercept"),
prior(normal(baseline_mean,
baseline_sd),
class = "b",
coef = input$baseline),
prior(normal(treatment_mean,
treatment_sd),
class = "b",
coef = input$group),
prior(cauchy(0, sigma_scale),
class = "sigma"))
list(
bayes = brm(ancovaformula(), data = sel_data(), silent = 1,
thin = 1, iter = input$iter, warmup = (input$iter/2),
prior = priors, stanvars = stanparams, seed = input$seed),
bayesx2 = brm(ancovaformula(), data = sel_data(), silent = 1,
thin = 1, iter = (input$iter)*2, warmup = input$iter,
prior = priors, stanvars = stanparams, seed = input$seed)
)
}
)
observeEvent(input$activate, {
bfit()
})
When this is run using the taskButton input$activate, however, it throws this error:
Warning: Error in : The following priors do not correspond to any model parameter:
b_input$baseline ~ normal(baseline_mean, baseline_sd)
b_input$group ~ normal(treatment_mean, treatment_sd)
Function 'default_prior' might be helpful to you.
Which suggests to me that, instead of interpreting the value of coef as that which is stored in the input$baseline variable, it reads in 'input$baseline' verbatim as the coefficient name.
How do I make it read the content of the variable instead, such that it interprets coef = input$baseline
as the name of the coefficient stored in input$baseline
, e.g. coef = measurement_1
?
Edit: The ancovaformula
variable is defined as:
ancovaformula <- reactive({
req(sel_data(), longdata())
ancovaformula = as.formula(paste(input$fwup, " ~ ", input$baseline,
" + ", input$group))
})
In which the inputs are character strings containing variable names, such that the final product, given values post, pre, and Tx, is:
post ~ pre + Tx
I managed to fix my issue using prior_string
as follows:
bfit <- eventReactive(
input$activate,
ignoreNULL = F,
{
req(lmmformula, anovaformula, ancovaformula)
validate(
need(input$upload != "", "Please upload a dataset in .xls or .xlsx
format"),
need(input$interceptMean != "", "Please enter mean of model intercept
prior"),
need(input$interceptVariance != "", "Please enter variance of model
intercept prior"),
need(input$baselineMean != "", "Please enter mean of baseline effect
prior"),
need(input$baselineVariance != "", "Please enter variance of baseline
effect prior"),
need(input$treatmentMean != "", "Please enter mean of treatment effect
prior"),
need(input$treatmentVariance != "", "Please enter variance of treatment
effect prior"),
need(input$sigmaScale != "", "Please enter scale of SD of outcome
prior"),
need(input$seed != "", "Please enter a seed for MCMC sampling")
)
stanparams <- stanvar(input$interceptMean, "intercept_mean") +
stanvar(sqrt(input$interceptVariance), "intercept_sd") +
stanvar(input$sigmaScale, "sigma_scale")
priors <- c(prior(normal(intercept_mean,
intercept_sd),
class = "Intercept"),
prior_string(paste0("normal(", input$baselineMean, ", ",
sqrt(input$baselineVariance), ")"),
class = "b",
paste0(input$baseline)),
prior_string(paste0("normal(", input$treatmentMean, ", ",
sqrt(input$treatmentVariance), ")"),
class = "b",
paste0(input$group)),
prior(cauchy(0, sigma_scale),
class = "sigma"))
list(
bayes = brm(ancovaformula(), data = sel_data(), silent = 1,
thin = 1, iter = input$iter, warmup = (input$iter/2),
prior = priors, stanvars = stanparams, seed = input$seed),
bayesx2 = brm(ancovaformula(), data = sel_data(), silent = 1,
thin = 1, iter = (input$iter)*2, warmup = input$iter,
prior = priors, stanvars = stanparams, seed = input$seed)
)
}
)
observeEvent(input$activate, {
bfit()
})