簡體   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