roxygen for namespace

62 views
Skip to first unread message

jonatho...@gmail.com

unread,
Mar 15, 2017, 4:56:10 PM3/15/17
to Stan users mailing list
Hello,

I'm just getting started on turning some Stan models into an R package.   I've used the rstan_skeleton_package function and followed the directions in the readme file.  The basic setup seems to be working.  I'm largely learning by reading through the rstanarm github and I've noticed that the NAMESPACE file was generated with roxygen.  Do you recommend this as standard practice?  If so where should the code to create the required lines, especially useDynLib(packageName, .registration = TRUE),  be generated? 

Any advice about how to transition to roxygen or whether or not it's worth transitioning, would be greatly appreciated.

Thanks,

Jonathon O'Brien

Ben Goodrich

unread,
Mar 15, 2017, 5:18:57 PM3/15/17
to Stan users mailing list
On Wednesday, March 15, 2017 at 4:56:10 PM UTC-4, jonatho...@gmail.com wrote:
Any advice about how to transition to roxygen or whether or not it's worth transitioning, would be greatly appreciated.

We would definitely recommend roxygen and there is actually a step where the cleanup script would break if you were not using roxygen. The useDynLib() line typically comes from the foo-package.R file (where foo is the name of your package) whose only R code is the terminating line

NULL

such as

https://github.com/stan-dev/rstanarm/blob/master/R/rstanarm-package.R

All the documentation is online at Hadley's website

http://r-pkgs.had.co.nz/

Ben



Jonathon O'Brien

unread,
Mar 15, 2017, 8:42:46 PM3/15/17
to stan-...@googlegroups.com
Thank you!  That file explains a lot.  

I just realized that there's another extremely basic piece that I don't understand.  How do I access the Stan model through R code?  There are Stan files and R files.  Is the Stan code is compiled on loading?    I saw a previous question where someone suggested calling sampling() on a pre-compiled object, but where do the objects live and how should they be accessed?   

Thanks again,

Jonathon

--
You received this message because you are subscribed to a topic in the Google Groups "Stan users mailing list" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/stan-users/BoP-b6ldGuw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to stan-users+unsubscribe@googlegroups.com.
To post to this group, send email to stan-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ben Goodrich

unread,
Mar 15, 2017, 8:49:46 PM3/15/17
to Stan users mailing list
On Wednesday, March 15, 2017 at 8:42:46 PM UTC-4, Jonathon O'Brien wrote:
Thank you!  That file explains a lot.  

I just realized that there's another extremely basic piece that I don't understand.  How do I access the Stan model through R code?  There are Stan files and R files.  Is the Stan code is compiled on loading?    I saw a previous question where someone suggested calling sampling() on a pre-compiled object, but where do the objects live and how should they be accessed?   

There should be a named list called stanmodels containing compiled stanmodel objects that is in your package's namespace but not exported. The names of the list elements are the same as the files in the exec/ directory but without the .stan extension. You can pass any of those to sampling(), optimizing(), or vb().

Ben

Jonathon O'Brien

unread,
Mar 20, 2017, 4:12:59 PM3/20/17
to stan-...@googlegroups.com
Thank you very much, knowing about the list was what I needed.

However, I still haven't figured out how to generate the NAMESPACE file with Roxygen.  With the NAMESPACE file that I created manually (per the instructions in the readme file) the package loads.  Now I have made a 'packagename-package.R' file by mimicking the example in the rstanarm package.  This should generate a NAMESPACE file with roxygen code.  But when I use the command devtools::document() I receive a warning that the NAMESPACE file was not originally created with roxygen and will not be overwritten.  If I delete the file, then I get an error.  Am I missing something obvious in this conversion?  

Thanks,

Jonathon

--

Jonah Gabry

unread,
Mar 20, 2017, 4:49:17 PM3/20/17
to Stan users mailing list
Hi Jonathon, 

What's the error message you get when you delete the NAMESPACE before running devtools::document()? 

Also, does it work if you add the line (by hand)

# Generated by roxygen2: do not edit by hand


to the top of your NAMESPACE file and then run document()?

Ben Goodrich

unread,
Mar 20, 2017, 4:55:51 PM3/20/17
to Stan users mailing list
On Monday, March 20, 2017 at 4:12:59 PM UTC-4, Jonathon O'Brien wrote:
Thank you very much, knowing about the list was what I needed.

However, I still haven't figured out how to generate the NAMESPACE file with Roxygen.  With the NAMESPACE file that I created manually (per the instructions in the readme file) the package loads.  Now I have made a 'packagename-package.R' file by mimicking the example in the rstanarm package.  This should generate a NAMESPACE file with roxygen code.  But when I use the command devtools::document() I receive a warning that the NAMESPACE file was not originally created with roxygen and will not be overwritten.  If I delete the file, then I get an error.  Am I missing something obvious in this conversion?  

Try moving your NAMESPACE file to a safe place. Then, in R, call roxygen2::roxygenize(clean = TRUE) when the working directory is the root of your package. Then do R CMD build, R CMD check, etc.

Ben

Jonathon O'Brien

unread,
Mar 20, 2017, 5:14:23 PM3/20/17
to stan-...@googlegroups.com
OK, I've got mixed results.

Jonah, your trick about adding the comment on the top worked.

Ben, your trick about deleting the file and using roxygen2::roxygenize(clean = TRUE) instead of devtools::document() also worked.

However, both of them generated an incorrect NAMESPACE file.  

For some reason this code
#' Bayesian Compositional Proteomics Modeling via Stan
#'
#' @docType package
#' @name compMS-package
#' @aliases compMS
#' @useDynLib compMS, .registration = TRUE
#'
#'  @import methods
#'  @importFrom rstan optimizing sampling vb constrain_pars extract
#'    extract_sparse_parts get_posterior_mean stanc
#'  @import stats
#'  @import Rcpp
#'  @import bayesplot
#'  @import rstantools

Generated this NAMESPACE file 

export(test_function)
useDynLib(compMS, .registration = TRUE @import methods @importFrom rstan optimizing sampling vb constrain_pars extract extract_sparse_parts get_posterior_mean stanc @import stats @import Rcpp @import bayesplot @import rstantools @description The \pkg{compMS} package enables users to fit compostional proteomics models for isobaric tag mass spectrometry experiments. The package is designed to make these models accesible to people without a background in Bayesian statistics or compositional data analysis. This is done by requiring users to follow a very specific format for data entry. Once the data if formatted properly everything else is handled internally. @section Model Details: This is where I will explain the model and the options for use: \describe{ Here is a detailed description. } @template reference-stan-manual)

Any idea what's going on here?

The full setup can be seen at https://github.com/ColtoCaro/compMS



--

Ben Goodrich

unread,
Mar 20, 2017, 5:34:30 PM3/20/17
to Stan users mailing list
On Monday, March 20, 2017 at 5:14:23 PM UTC-4, Jonathon O'Brien wrote:
#' Bayesian Compositional Proteomics Modeling via Stan
#'
#' @docType package
#' @name compMS-package
#' @aliases compMS
#' @useDynLib compMS, .registration = TRUE
#'

Your spacing gets messed up starting on the next line. All the @ symbols need to be exactly one space from the #'
 
#'  @import methods
#'  @importFrom rstan optimizing sampling vb constrain_pars extract
#'    extract_sparse_parts get_posterior_mean stanc

Put the above all on one line.
 
#'  @import stats
#'  @import Rcpp
#'  @import bayesplot
#'  @import rstantools

Too much space between #' and @ again.

If you get it to look like this, then the NAMESPACE comes out right

# File for creating compMS documentation with roxygen


#' Bayesian Compositional Proteomics Modeling via Stan
#'
#' @docType package
#' @name compMS-package
#' @aliases compMS
#' @useDynLib compMS, .registration = TRUE
#'
#' @import methods
#' @importFrom rstan optimizing sampling vb constrain_pars extract extract_sparse_parts get_posterior_mean stanc

#' @import stats
#' @import Rcpp
#' @import bayesplot
#' @import rstantools
#'
#' @description
#'  The \pkg{compMS} package enables users to fit compostional proteomics
#'  models for isobaric tag mass spectrometry experiments.  The package is
#'  designed to make these models accesible to people without a background
#'  in Bayesian statistics or compositional data analysis.  This is done by
#'  requiring users to follow a very specific format for data entry.  Once
#'  the data if formatted properly everything else is handled internally.
#'
#'  @section Model Details:
#'  This is where I will explain the model and the options for use:
#'  \describe{
#'  Here is a detailed description.
#'  }
#'
#'  @template reference-stan-manual
#'
NULL

Also, you can delete R/compMS-internal.R.

Ben

Jonah Sol Gabry

unread,
Mar 20, 2017, 5:53:53 PM3/20/17
to stan-...@googlegroups.com
Hmm, we should probably make  rstan_package_skeleton do a bit more of this work. Maybe it can include the beginnings of the packageName-package.R file. That might help avoid this problem. 

Jonah

--
You received this message because you are subscribed to a topic in the Google Groups "Stan users mailing list" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/stan-users/BoP-b6ldGuw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to stan-users+...@googlegroups.com.

Jonathon O'Brien

unread,
Mar 20, 2017, 6:13:03 PM3/20/17
to stan-...@googlegroups.com
The spacing worked!  Much appreciated.  

To unsubscribe from this group and all its topics, send an email to stan-users+unsubscribe@googlegroups.com.

To post to this group, send email to stan-...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups "Stan users mailing list" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/stan-users/BoP-b6ldGuw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to stan-users+unsubscribe@googlegroups.com.

Jonathon O'Brien

unread,
Mar 22, 2017, 2:10:24 PM3/22/17
to stan-...@googlegroups.com
It seems that I don't understand the basics of how to work with the model objects created when the package loads.

I'm working with a very simple Stan model, just to test everything out. The file is called "testModel.stan" In my usual workflow I would have code like this;

y_ <- rnorm(100,5,5)
N <- length(y_)
sFit <- stan(file = "testModel.stan")
summary(sFit)

This code works fine, in the respect that the posterior mean is close to 5.  However, when working in a package the code is altered and the results are off.

y_ <- rnorm(100,5,5)
N <- length(y_)
sFit <- sampling(stanmodels$testModel)
summary(sFit)

This executes without any errors.  However, the answers are wrong, with the posterior mean centered around zero.  Am I doing something obviously stupid here?  Stan code is below in case you want to see it.

Thanks,

Jonathon


data{
  int<lower=0> N ;
  real y_[N] ;
}

parameters{
real beta ;
}

model{
beta ~ normal(0, 10) ;
for (i in 1:N){
y_[i] ~ normal(beta, 1) ;
}
}



Ben Goodrich

unread,
Mar 22, 2017, 3:10:16 PM3/22/17
to Stan users mailing list
On Wednesday, March 22, 2017 at 2:10:24 PM UTC-4, Jonathon O'Brien wrote:
This executes without any errors.  However, the answers are wrong, with the posterior mean centered around zero.  Am I doing something obviously stupid here?  Stan code is below in case you want to see it.

The testModel.stan file that you have in the master branch of your GitHub repository is different:

goodrich@T540p:/tmp$ cat compMS/exec/testModel.stan
parameters{
real beta;
}

model{
beta ~ normal(0,3);
}

That answer you obtained is plausible for that model. You need to save your new compMS/exec/testModel.stan and then do

R CMD build compMS && R CMD INSTALL compMS_*.tar.gz

Ben

Jonathon O'Brien

unread,
Mar 22, 2017, 4:14:13 PM3/22/17
to stan-...@googlegroups.com
Sorry about that, I hadn't pushed the local changes to Github.  It's updated now.  

I have no idea what's going on.  Executing your code, and then starting an R session from the command prompt works.  I can access the model and the summary looks correct.  But in Rstudio it still fails.  The files are the same.  I use devtools::loadall() then run the same code to execute the model and it still gives me a mean of zero.  

Making this even more bizarre, when enter the function name for the stan code it returns the correct Stan function.  The following R session demonstrates the problem.


> stanmodels$testModel
S4 class stanmodel 'testModel' coded as follows:

data{
  int<lower=0> N ;
  real y_[N] ;
}

parameters{
real beta ;
}

model{
beta ~ normal(0, 10) ;
for (i in 1:N){
y_[i] ~ normal(beta, 1) ;
}
} 
> y_ <- rnorm(100,5,5)
> N <- length(y_)
> sFit <- sampling(stanmodels$testModel)
Error: could not find function "sampling"
> sFit <- rstan::sampling(stanmodels$testModel)

SAMPLING FOR MODEL 'testModel' NOW (CHAIN 1).

Chain 1, Iteration:    1 / 2000 [  0%]  (Warmup)
Chain 1, Iteration:  200 / 2000 [ 10%]  (Warmup)
Chain 1, Iteration:  400 / 2000 [ 20%]  (Warmup)
Chain 1, Iteration:  600 / 2000 [ 30%]  (Warmup)
Chain 1, Iteration:  800 / 2000 [ 40%]  (Warmup)
Chain 1, Iteration: 1000 / 2000 [ 50%]  (Warmup)
Chain 1, Iteration: 1001 / 2000 [ 50%]  (Sampling)
Chain 1, Iteration: 1200 / 2000 [ 60%]  (Sampling)
Chain 1, Iteration: 1400 / 2000 [ 70%]  (Sampling)
Chain 1, Iteration: 1600 / 2000 [ 80%]  (Sampling)
Chain 1, Iteration: 1800 / 2000 [ 90%]  (Sampling)
Chain 1, Iteration: 2000 / 2000 [100%]  (Sampling)
 Elapsed Time: 0.009186 seconds (Warm-up)
               0.007671 seconds (Sampling)
               0.016857 seconds (Total)


SAMPLING FOR MODEL 'testModel' NOW (CHAIN 2).

Chain 2, Iteration:    1 / 2000 [  0%]  (Warmup)
Chain 2, Iteration:  200 / 2000 [ 10%]  (Warmup)
Chain 2, Iteration:  400 / 2000 [ 20%]  (Warmup)
Chain 2, Iteration:  600 / 2000 [ 30%]  (Warmup)
Chain 2, Iteration:  800 / 2000 [ 40%]  (Warmup)
Chain 2, Iteration: 1000 / 2000 [ 50%]  (Warmup)
Chain 2, Iteration: 1001 / 2000 [ 50%]  (Sampling)
Chain 2, Iteration: 1200 / 2000 [ 60%]  (Sampling)
Chain 2, Iteration: 1400 / 2000 [ 70%]  (Sampling)
Chain 2, Iteration: 1600 / 2000 [ 80%]  (Sampling)
Chain 2, Iteration: 1800 / 2000 [ 90%]  (Sampling)
Chain 2, Iteration: 2000 / 2000 [100%]  (Sampling)
 Elapsed Time: 0.00764 seconds (Warm-up)
               0.00781 seconds (Sampling)
               0.01545 seconds (Total)


SAMPLING FOR MODEL 'testModel' NOW (CHAIN 3).

Chain 3, Iteration:    1 / 2000 [  0%]  (Warmup)
Chain 3, Iteration:  200 / 2000 [ 10%]  (Warmup)
Chain 3, Iteration:  400 / 2000 [ 20%]  (Warmup)
Chain 3, Iteration:  600 / 2000 [ 30%]  (Warmup)
Chain 3, Iteration:  800 / 2000 [ 40%]  (Warmup)
Chain 3, Iteration: 1000 / 2000 [ 50%]  (Warmup)
Chain 3, Iteration: 1001 / 2000 [ 50%]  (Sampling)
Chain 3, Iteration: 1200 / 2000 [ 60%]  (Sampling)
Chain 3, Iteration: 1400 / 2000 [ 70%]  (Sampling)
Chain 3, Iteration: 1600 / 2000 [ 80%]  (Sampling)
Chain 3, Iteration: 1800 / 2000 [ 90%]  (Sampling)
Chain 3, Iteration: 2000 / 2000 [100%]  (Sampling)
 Elapsed Time: 0.010079 seconds (Warm-up)
               0.008844 seconds (Sampling)
               0.018923 seconds (Total)


SAMPLING FOR MODEL 'testModel' NOW (CHAIN 4).

Chain 4, Iteration:    1 / 2000 [  0%]  (Warmup)
Chain 4, Iteration:  200 / 2000 [ 10%]  (Warmup)
Chain 4, Iteration:  400 / 2000 [ 20%]  (Warmup)
Chain 4, Iteration:  600 / 2000 [ 30%]  (Warmup)
Chain 4, Iteration:  800 / 2000 [ 40%]  (Warmup)
Chain 4, Iteration: 1000 / 2000 [ 50%]  (Warmup)
Chain 4, Iteration: 1001 / 2000 [ 50%]  (Sampling)
Chain 4, Iteration: 1200 / 2000 [ 60%]  (Sampling)
Chain 4, Iteration: 1400 / 2000 [ 70%]  (Sampling)
Chain 4, Iteration: 1600 / 2000 [ 80%]  (Sampling)
Chain 4, Iteration: 1800 / 2000 [ 90%]  (Sampling)
Chain 4, Iteration: 2000 / 2000 [100%]  (Sampling)
 Elapsed Time: 0.008695 seconds (Warm-up)
               0.009061 seconds (Sampling)
               0.017756 seconds (Total)

> summary(sFit)
 Length   Class    Mode 
      1 stanfit      S4 
> rstan::summary(sFit)
$summary
            mean    se_mean        sd      2.5%        25%         50%         75%
beta -0.02590212 0.05818694 2.9970952 -5.904818 -2.0469506  0.05013002  2.04953047
lp__ -0.49894472 0.01778113 0.7233716 -2.541551 -0.6384535 -0.23334478 -0.04091759

Any idea what's going on? 

Thanks,

Jonathon

--

Ben Goodrich

unread,
Mar 22, 2017, 4:39:14 PM3/22/17
to Stan users mailing list
On Wednesday, March 22, 2017 at 4:14:13 PM UTC-4, Jonathon O'Brien wrote:
Any idea what's going on? 
 
You need to be using the stanmodels list from the compMS namespace, rather than whatever stale version you have in the global namespace; i.e. this works for me

sFit <- rstan::sampling(compMS:::stanmodels$testModel)
sFit
Inference for Stan model: testModel.
4 chains, each with iter=2000; warmup=1000; thin=1;
post
-warmup draws per chain=1000, total post-warmup draws=4000.

         mean se_mean   sd    
2.5%      25%      50%      75%    97.5% n_eff Rhat
beta    
4.15    0.00 0.10     3.95     4.08     4.15     4.22     4.36  2545    1
lp__
-1513.06    0.02 0.75 -1515.22 -1513.25 -1512.77 -1512.57 -1512.52  1626    1

Ben

Jonathon O'Brien

unread,
Mar 22, 2017, 4:56:26 PM3/22/17
to stan-...@googlegroups.com
Unfortunately, that's not doing the trick.

> mean(y_)
[1] 5.27169
> sFit <- rstan::sampling(compMS:::stanmodels$testModel)
> sFit
Inference for Stan model: testModel.
4 chains, each with iter=2000; warmup=1000; thin=1; 
post-warmup draws per chain=1000, total post-warmup draws=4000.

      mean se_mean   sd  2.5%   25%   50%   75% 97.5% n_eff Rhat
beta -0.04    0.06 3.02 -5.83 -2.20 -0.11  2.09  5.86  2579    1
lp__ -0.51    0.02 0.70 -2.51 -0.67 -0.25 -0.06  0.00  1390    1

Samples were drawn using NUTS(diag_e) at Wed Mar 22 16:49:55 2017.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
> compMS:::stanmodels$testModel
S4 class stanmodel 'testModel' coded as follows:

data{
  int<lower=0> N ;
  real y_[N] ;
}

parameters{
real beta ;
}

model{
beta ~ normal(0, 10) ;
for (i in 1:N){
y_[i] ~ normal(beta, 1) ;
}
} 

I really don't see how this is possible.  Unless you've got another suggestion, I'm going to try deleting everything and downloading a fresh version from Github.  


Jonathon O'Brien

unread,
Mar 22, 2017, 9:06:13 PM3/22/17
to stan-...@googlegroups.com
OK, I've got a clue about what's happening and it might be relevant to others who are learning from Hadley's R Packages book.  

The error in R Studio persists.  What's new is that I can now replicate the error from the command line.  If I only enter R CMD build compMS
while skipping the install R CMD INSTALL compMS_*.tar.gz and then start an R session, calling the Stan model fits the wrong model.  I suspect that means that the functions built into devtools are not doing a full install.  Specifically devtools::loadall() seems to not do everything that is needed here.  Does this guess make sense to you? Do you know of any way to get everything in place with the tools provide by Rstudio?

Thanks,

Jonathon

Ben Goodrich

unread,
Mar 22, 2017, 11:16:15 PM3/22/17
to Stan users mailing list
On Wednesday, March 22, 2017 at 9:06:13 PM UTC-4, Jonathon O'Brien wrote:
OK, I've got a clue about what's happening and it might be relevant to others who are learning from Hadley's R Packages book.  

The error in R Studio persists.  What's new is that I can now replicate the error from the command line.  If I only enter R CMD build compMS
while skipping the install R CMD INSTALL compMS_*.tar.gz and then start an R session, calling the Stan model fits the wrong model.  I suspect that means that the functions built into devtools are not doing a full install.  Specifically devtools::loadall() seems to not do everything that is needed here.  Does this guess make sense to you? Do you know of any way to get everything in place with the tools provide by Rstudio?

Yeah, I don't think devtools::loadall() with recompile = FALSE (the default) is sufficient but maybe with recompile = TRUE? Anyway, the build options in the Git tab of RStudio work for developing rstanarm.

Ben

Jonathon O'Brien

unread,
Mar 23, 2017, 12:35:39 PM3/23/17
to stan-...@googlegroups.com
recompile = TRUE solved the problem.  Thanks!  

--
Reply all
Reply to author
Forward
0 new messages