calling Stan from R

49 views
Skip to first unread message

Andrew Gelman

unread,
Apr 10, 2015, 2:36:47 PM4/10/15
to stan...@googlegroups.com
Hi, there was a discussion recently about using global or local environments in the Stan call. I tried running stan() with the argument data=.GlobalEnv but it didn’t run so I must have been doing something wrong. (I actually wanted to specify the local environment but I couldn’t remember what it was called.)

Also, the question came up as to why I wanted to do this. Ben recommended that I write my Stan functions more generically (with variables such as x,y rather than income,vote or whatever). Even so, things can get messy. For example, from something I happen to be working on right now:

fit1 <- stan("extrap_impsampling.stan”, data=c("J","T","J_prime","T_prime","y","y_prime_bar","x","x_prime","mu_delta_p","Sigma_delta_p","mu_delta_g","Sigma_delta_g","J_tilde","K"), iter=1000, chains=4, seed=0)

Keeping all these parameters in the data list, it’s just bookkeeping and a waste of time. This is an example of where it would help to just pass the local environment.

A

Ben Goodrich

unread,
Apr 10, 2015, 3:29:32 PM4/10/15
to stan...@googlegroups.com, gel...@stat.columbia.edu
fit1_env <- new.env()
fit1_env$J
<- J
...
fit1_env$K
<- K
fit1
<- stan("extrap_impsampling.stan", data = fit1_env, iter = 1000, chains = 4, seed = 0)

Ben

Andrew Gelman

unread,
Apr 10, 2015, 4:37:19 PM4/10/15
to Ben Goodrich, stan...@googlegroups.com
Wait, you’re kidding, right??  This is more lines of code than simply doing data=c(“J”,”T”,…)!

Ben Goodrich

unread,
Apr 10, 2015, 5:42:25 PM4/10/15
to stan...@googlegroups.com, gel...@stat.columbia.edu
On Friday, April 10, 2015 at 4:37:19 PM UTC-4, Andrew Gelman wrote:
Wait, you’re kidding, right??  This is more lines of code than simply doing data=c(“J”,”T”,…)!

I presumed you were creating the environment to swap things in and out calling stan() a bunch of times. If you were only calling stan() once, then I wouldn't do it my way. I guess you could do it in 2 lines

fit1_env <- new.env()
invisible
(sapply(c("J", ..., "K"), FUN = function(x) assign(x, get(x), envir = fit1_env)))

Since no one has objected to me putting something like this inside sampling(), optimizing(), etc., I guess we can do it.

parse_data <- function(program, e = parent.frame()) {
  cppcode
<- scan(what = character(), sep = "\n", quiet = TRUE,
                  text
= stanc(program)$cppcode)
 
private <- grep("^private:", cppcode) + 1L
 
public <- grep("^public:", cppcode) - 1L
 
# pull out object names from the data block
  objects
<- gsub("^.* ([0-9A-Za-z_]+).*;.*$", "\\1",
                  cppcode
[private:public])
 
# get them from the calling environment
  mget
(objects, envir = e, inherits = TRUE,
       ifnotfound
= vector("list", length(objects)))
}

Ben

Andrew Gelman

unread,
Apr 10, 2015, 6:03:03 PM4/10/15
to Ben Goodrich, stan...@googlegroups.com
Hi, but I don’t want to even do that, as it still requires me to creat the list, c(“J”, …, "K").  

What I really really want is to call Stan using whatever’s sitting there in R, like this:

stan(“test.stan”, data=local.env(), …) or whatever.

My whole point here is that I _don’t_ want to have to list the variable names in the function call, as that is duplicative; it should be the default that the stan() call looks for the data in the local environment and then lets me know if something’s not there (or is not the right size/shape).

A

Ben Goodrich

unread,
Apr 10, 2015, 6:06:52 PM4/10/15
to stan...@googlegroups.com, gel...@stat.columbia.edu
On Friday, April 10, 2015 at 6:03:03 PM UTC-4, Andrew Gelman wrote:
Hi, but I don’t want to even do that, as it still requires me to creat the list, c(“J”, …, "K").  

What I really really want is to call Stan using whatever’s sitting there in R, like this:

stan(“test.stan”, data=local.env(), …) or whatever.

My whole point here is that I _don’t_ want to have to list the variable names in the function call, as that is duplicative; it should be the default that the stan() call looks for the data in the local environment and then lets me know if something’s not there (or is not the right size/shape).

This function does that; we just need to either put it in or have someone object to it.

Andrew Gelman

unread,
Apr 10, 2015, 6:34:42 PM4/10/15
to Ben Goodrich, stan...@googlegroups.com
Oh, sorry, I didn’t catch that.
A

Bob Carpenter

unread,
Apr 10, 2015, 9:55:57 PM4/10/15
to stan...@googlegroups.com
I don't understand the matching in the R code or
the environment manipulation, but that's not an issue.
Assuming it does the right thing with arrays and vectors
and all the data types and isn't whitespace sensitive
in a way that Stan's not, it should be OK in the short
term. I'd feel more confident if there were a thorough
set of unit tests around it.

Longer term, I'm going to get around to doing better
name mangling at which point this is likely to fail and
have to be updated.

I would prefer a solution that actually queried the model
for variable names which we could make part of the stable
model API, but then somebody would have to do
the code generation for that, and Andrew's brought this up
so many times I know he doesn't want to wait.

- Bob
> --
> You received this message because you are subscribed to the Google Groups "stan development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to stan-dev+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Andrew Gelman

unread,
Apr 10, 2015, 9:57:30 PM4/10/15
to stan...@googlegroups.com
No, I can wait. It’s not urgent, it’s just a user-friendliness thing. I’ve been doing stan demos in my class every week for awhile now, and it always seems a bit awkward to have to specify the variables each time.

Ben Goodrich

unread,
Apr 11, 2015, 11:18:32 AM4/11/15
to stan...@googlegroups.com
On Friday, April 10, 2015 at 9:55:57 PM UTC-4, Bob Carpenter wrote:
I would prefer a solution that actually queried the model
for variable names which we could make part of the stable
model API, but then somebody would have to do
the code generation for that, and Andrew's brought this up
so many times I know he doesn't want to wait.

Yeah, that would be better but the C++ code is pretty easy to grep for the names of the object in the data block. This just creates a list of objects by searching through the stack of R environments for objects that have the same names as objects in the data block of the Stan program. From there, the behavior would be the same as if the user had passed such a list to stan().

Ben
Reply all
Reply to author
Forward
0 new messages