Hello cmdstanr fans!
As you may know, I love using cmdstanr for teaching newcomers to Stan and Bayes in general. But I find a couple of syntactical things that throw some of them. It’s really a question of what one is used to. Some find the OOP-style methods strange and it’s little bit of unnecessary cognitive load for them. I mean mymodel$sample(), for example, rather than sample(mymodel…). Another is that those who like to pipe R code left-to-right can’t do so.
My personal preferences are to get as close to functional programming as i can, though I think it’s an ideal and a state of mind rather than a product one can use. I therefore don’t like methods and I don’t like pipes. However, I just want to make it easier for beginners.
SO… I played very briefly with defining new functions (see below) that would be alternatives to the methods $sample() and $draws() and it works ok. But is there any reason why I should be cautious in doing this? Is there something deep in cmdstanr that will trip up learners using this? I’m especially hoping for some insights from @mitzimorris here.
library(cmdstanr)
library(bayesplot)
library(magrittr)
set.seed(1234)
passign <- function(x, name) {
assign(name, x, pos=1)
return(x)
}
cmdstan_sample <- function(model, ...) {
model$sample(...)
}
cmdstan_draws <- function(fitted, ...) {
fitted$draws(...)
}
cmdstan_summary <- function(fitted, ...) {
fitted$summary(...)
}
standata <- list(n=100, x=rnorm(100, 10, 2))
stancode <- '
data {
int n;
array[n] real x;
}
parameters {
real mu;
real<lower=0> sigma;
}
model {
mu ~ normal(0, 10);
sigma ~ normal(0,2);
x ~ normal(mu, sigma);
}
'
######### pipe version #########
stancode %>% write_stan_file() %>%
cmdstan_model(compile=TRUE) %>%
cmdstan_sample(data=standata,
seed=123,
chains=2,
parallel_chains=2,
iter_warmup=1000,
iter_sampling=2000) %>%
passign("stansamples") %T>%
cmdstan_summary() %>%
cmdstan_draws() %>%
passign("standraws") %>%
mcmc_trace()
######### non-pipe version ########
stanmod <- cmdstan_model(write_stan_file(stancode), compile=TRUE)
stansamples <- cmdstan_sample(stanmod,
data=standata,
seed=123,
chains=2,
parallel_chains=2,
iter_warmup=1000,
iter_sampling=2000)
cmdstan_summary(stansamples)
standraws <- cmdstan_draws(stansamples)
mcmc_trace(standraws)
Of course, you don’t have to pipe this, and you can use the more recent “native R pipe”. One thing that’s probably worth saying is that beginners need to learn each step individually, and in particular need to recognise what the errors and warnings look like from each, before they chain them together. So piping is not for day 1.
Thanks for any ideas and tips,
Robert