繁体   English   中英

从新的 package 命名空间中的 Rcpp function 加载 R 包的 function

[英]Loading a R package's function from Rcpp function in a new package namespace

我正在为 R 开发 package,并希望在 Rcpp function 中加载 R package 的功能。

我知道 Rcpp::Environment env("package:package_of_interest"),但这仅在通过库("package_of_interest")从 R 加载“package_of_interest”时有效。 此外,我在 DEPENDS 下面的 DESCRIPTION 文件中添加了“package_of_interest”。 这意味着,每当我在 R 中使用库(“my_package”)加载我的 package 时,所有功能都会自动加载,因为所需的 package 会自动加载。 但是,如果我通过 my_package::my_functionX(...) 调用 function,它会抛出一个错误并声明它无法将 object 转换为环境:[type=character; 目标 = ENVSXP]。 在此处输入图像描述 有什么办法可以解决这个问题吗? 我可以将输入(字符)转换为目标(ENVSXP)吗?

我之前通过环境 Rcpp 研究了从 c++ 调用 functionRcpp trouble importing 'hessian' from R package 'numDeriv'并通过我的方法得到了确认。

在下文中,我给你一个最小的例子来重现错误。 首先调用 library(bigmemory) ,这将起作用,但没有。

#include <iostream>
// [[Rcpp::depends(RcppArmadillo, BH, bigmemory)]]
#include <bigmemory/BigMatrix.h>
#include <bigmemory/MatrixAccessor.hpp>
#include <RcppArmadillo.h>
#include <Rdefines.h>
    
    
// [[Rcpp::export]]
void test_make_bm(std::size_t nrows, std::size_t ncols, std::string type, 
    bool separated = false, bool binarydescriptor = false, bool shared = true)
{

    // this line drops the error
    Rcpp::Environment bigmemory = Rcpp::Environment("package:bigmemory");
    // you can also directly call Rcpp::Environment bigmemory("package:bigmemory")
    
    Rcpp::Function big_matrix = bigmemory["big.matrix"];
            
    SEXP bm = big_matrix(
            Rcpp::_["nrow"] = nrows,
            Rcpp::_["ncol"] = ncols,
            Rcpp::_["type"] = type,
            Rcpp::_["init"] = R_NilValue,
            Rcpp::_["dimnames"] = R_NilValue,
            Rcpp::_["separated"] = separated,
            Rcpp::_["backingfile"] = R_NilValue,
            Rcpp::_["backingpath"] = R_NilValue,
            Rcpp::_["descriptorfile"] = R_NilValue,
            Rcpp::_["binarydescriptor"] = binarydescriptor,
            Rcpp::_["shared"] = shared);
        
    SEXP address = GET_SLOT(bm, Rf_install("address"));
    Rcpp::XPtr<BigMatrix> xptr(address);
        
    arma::mat m((double*) xptr->matrix(), xptr->nrow(), xptr->ncol());
    m.print();
    Rcpp::Rcout << "\n";
          
    return;

}

有没有办法从 Rcpp 加载 package? 有谁知道为什么bigmemory的BigMatrix在C++没有构造函数?

这与其中一个单元测试文件基本相同,只要它存在,就已经记录了这种行为。 如果您需要尚未附加的 package 中的 function,则需要通过命名空间连接到 go。

> Rcpp::cppFunction(paste0("double mysd(NumericVector x) { ", 
       r"(Environment ns = Environment::namespace_env("stats");)", 
       r"(Function f = ns["sd"]; return as<double>(f(x)); })"))
> mysd(1:10)
[1] 3.02765
> mysd(1:10)
[1] 3.02765
> 

(为了可读性,我将cppFunction()调用分为三行,但你可以只写一行,这也是我编写它来测试它的方式。)

因此,经过一番研究,我向您介绍了解决方案。 为了访问 packagename::package_function() 功能,您必须使用 Environment 命名空间中的 namespace_env function。

#include <iostream>
// [[Rcpp::depends(RcppArmadillo, BH, bigmemory)]]
#include <bigmemory/BigMatrix.h>
#include <bigmemory/MatrixAccessor.hpp>
#include <RcppArmadillo.h>
#include <Rdefines.h>

// [[Rcpp::export]]
void test_make_bm(std::size_t nrows, std::size_t ncols, std::string type, 
    bool separated = false, bool binarydescriptor = false, bool shared = true)
{
Rcpp::Environment bigmemory = Rcpp::Environment::namespace_env("bigmemory");
   Rcpp::Function big_matrix = bigmemory["big.matrix"];
            
   SEXP bm = big_matrix(
            Rcpp::_["nrow"] = nrows,
            Rcpp::_["ncol"] = ncols,
            Rcpp::_["type"] = type,
            Rcpp::_["init"] = R_NilValue,
            Rcpp::_["dimnames"] = R_NilValue,
            Rcpp::_["separated"] = separated,
            Rcpp::_["backingfile"] = R_NilValue,
            Rcpp::_["backingpath"] = R_NilValue,
            Rcpp::_["descriptorfile"] = R_NilValue,
            Rcpp::_["binarydescriptor"] = binarydescriptor,
            Rcpp::_["shared"] = shared);
        
    SEXP address = GET_SLOT(bm, Rf_install("address"));
    Rcpp::XPtr<BigMatrix> xptr(address);
        
    arma::mat m((double*) xptr->matrix(), xptr->nrow(), xptr->ncol());
    m.print();
    Rcpp::Rcout << "\n";
          
    return;   
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM