我正在编写一个将rstan
用于贝叶斯的R包
采样。 (Here
如果您想重现此问题,则是特定的提交。)我仅在
运行一个从小插图调用rstan
的函数(如果我使用的话)
library(rstan)
,但没有一些解决方法。
包中的一个函数调用rstan
(为清楚起见进行了编辑):
#' @importFrom Rcpp cpp_object_initializer
#' @export
run_variational_bayes <- function(x, y, output_samples, beta_sd, stan_file) {
n_input <- length(y)
p <- ncol(x)
train_dat <- list(n = n_input, p = p, x = x, y = y, beta_sd = beta_sd)
stan_model <- rstan::stan_model(file = stan_file)
stan_vb <- rstan::vb(object = stan_model, data = train_dat,
output_samples = output_samples)
return(rstan::extract(stan_vb)$beta)
}
我在软件包中测试了此功能:
context("RStan variational Bayes model")
test_that("Rstan variational Bayes model runs", {
german <- PosteriorBootstrap::get_german_credit_dataset()
n_bootstrap <- 10
prior_variance <- 100
stan_vb_sample <- PosteriorBootstrap::run_variational_bayes(x = german$x,
y = german$y,
output_samples = n_bootstrap,
beta_sd = sqrt(prior_variance),
iter = 10)
expect_true(nrow(stan_vb_sample) == n_bootstrap)
expect_true(ncol(stan_vb_sample) == ncol(german$x))
})
测试在本地和Travis上通过,因此该功能可从 包。
如果我包含library(rstan)
,小插图代码将起作用:
library(rstan)
prior_sd <- 10
n_bootstrap <- 1000
german <- PosteriorBootstrap::get_german_credit_dataset()
stan_vb_sample <- PosteriorBootstrap::run_variational_bayes(x = german$x,
y = german$y,
output_samples = n_bootstrap,
beta_sd = prior_sd)
dim(stan_vb_sample)
#> [1] 1000 25
但是我认为用户需要将另一个软件包附加到
用我的包裹。如果我使用requireNamespace()
,则可以构建小插图,但是
Stan模型无法运行:
requireNamespace("PosteriorBootstrap", quietly = TRUE)
# ...
stan_vb_sample <- PosteriorBootstrap::run_variational_bayes(x = german$x,
y = german$y,
output_samples = n_bootstrap,
beta_sd = prior_sd)
#> Error in cpp_object_initializer(.self, .refClassDef, ...) :
#> could not find function "cpp_object_initializer"
#> failed to create the model; variational Bayes not done
#> Stan model 'bayes_logit' does not contain samples.
dim(stan_vb_sample)
#> NULL
请注意,我在Roxygen中使用了#' @importFrom Rcpp cpp_object_initializer
注释,应该导入rstan
说的功能丢失。
rstan
的软件包的比较 This package
在DESCRIPTION
中具有相似的值,但是我测试了它不需要library(rstan)
运行rstan
。我在一个函数中使用了@import Rcpp
通过替换@importFrom Rcpp cpp_object_initializer
功能并出现相同的错误。
requireNamespace()
和library()
之间的区别在于后者
将包的名称空间导入当前环境。但
rstan
进行了import(Rcpp)
,因此该对象应该可用。
(1)我在小插图中尝试了library("PosteriorBootstrap")
,因为
包将该对象导入其名称空间:我遇到了相同的错误(
@import Rcpp
或@importFrom Rcpp cpp_object_initializer
)。
(2)我将该对象复制到函数的环境中:
requireNamespace("Rcpp", quietly = TRUE)
#' @import Rcpp
#' @export
run_variational_bayes <- function(x, y, output_samples, beta_sd,
stan_file = get_stan_file(),
iter = 10000, seed = 123, verbose = FALSE) {
cpp_object_initializer <- Rcpp:cpp_object_initializer
# ...
}
我很惊讶地得到一个小插图错误:
E creating vignettes (1.8s)
Quitting from lines 151-157 (anpl.Rmd)
Error: processing vignette 'anpl.Rmd' failed with diagnostics:
object 'Rcpp' not found
Execution halted
作为一个临时解决方案,我将函数中的代码移到了小插图
完全。小插图以requireNamespace()
失败:
requireNamespace("rstan")
#> Loading required namespace: rstan
prior_sd <- 10
n_bootstrap <- 1000
german <- PosteriorBootstrap::get_german_credit_dataset()
train_dat <- list(n = length(german$y), p = ncol(german$x), x = german$x, y = german$y, beta_sd = prior_sd)
stan_file <- PosteriorBootstrap::get_stan_file()
stan_model <- rstan::stan_model(file = stan_file)
stan_vb <- rstan::vb(object = stan_model, data = train_dat, seed = seed,
output_samples = n_bootstrap)
#> Error in cpp_object_initializer(.self, .refClassDef, ...) :
#> could not find function "cpp_object_initializer"
#> failed to create the model; variational Bayes not done
stan_vb_sample <- rstan::extract(stan_vb)$beta
#> Stan model 'bayes_logit' does not contain samples.
dim(stan_vb_sample)
#> NULL
并以library(rstan)
成功:
library("rstan")
#> Loading required package: ggplot2
# ...
stan_model <- rstan::stan_model(file = stan_file)
stan_vb <- rstan::vb(object = stan_model, data = train_dat, seed = seed,
output_samples = n_bootstrap)
#> Chain 1: ------------------------------------------------------------
# ...
#> Chain 1: COMPLETED.
stan_vb_sample <- rstan::extract(stan_vb)$beta
dim(stan_vb_sample)
#> [1] 1000 25
在将代码移出软件包时,我意识到一个使用
library("rstan")
并直接调用rstan
程序包,例如
context("Adaptive non-parametric learning function")
library("rstan")
# ...
test_that("Adaptive non-parametric learning with posterior samples works", {
german <- get_german_credit_dataset()
n_bootstrap <- 100
# Get posterior samples
seed <- 123
prior_sd <- 10
train_dat <- list(n = length(german$y), p = ncol(german$x), x = german$x,
y = german$y, beta_sd = prior_sd)
stan_model <- rstan::stan_model(file = get_stan_file())
stan_vb <- rstan::vb(object = stan_model, data = train_dat, seed = seed,
output_samples = n_bootstrap)
stan_vb_sample <- rstan::extract(stan_vb)$beta
# ...
}
通过软件包内的测试:
✔ | 24 | Adaptive non-parametric learning function [53.1 s]
══ Results ═════════════════════════════════════════════════════════════════════
Duration: 53.2 s
OK: 24
Failed: 0
Warnings: 0
Skipped: 0
但使用requireNamespace("rstan")
进行的相同测试未通过:
⠋ | 21 | Adaptive non-parametric learning functionError in cpp_object_initializer(.self, .refClassDef, ...) :
could not find function "cpp_object_initializer"
Stan model 'bayes_logit' does not contain samples.
...
══ Results ═════════════════════════════════════════════════════════════════════
Duration: 51.7 s
OK: 22
Failed: 1
Warnings: 0
Skipped: 0
我想知道rstan
代码是否在不使用{
限定符,如果它是在不继承
调用环境中的对象。
我承认我没有使用cpp_object_initializer
来启动程序包
(我的雇主决定坚持使用MIT许可证,并选择不重新启动
包结构从头开始)和我正在编译
通话时的模型。我想用户提供自己的模型会
使用rstantools
代替requireNamespace()
时会遇到相同的错误。
如何允许用户运行调用library()
的程序包函数而无需
rstan
,还没用library(rstan)
从头开始重启软件包吗?