C++ 和 R : Create a . so 或 .dll

标签 c++ r compilation rcpp

我有疑问。我知道可以从 cpp 文件调用 R 函数。

  • 但可以将该 cpp 文件(内部有一个 R 函数 - 来自包,例如 caret -)编译为 .so 还是dll
  • 如果可能的话。里面有一堆R代码是如何工作的。编译后的代码在编译之前是否调用 R 解释器,或者不需要?

提前致谢

最佳答案

是的,您可以将 R 嵌入到 C 或 C++ 应用程序中。该 API 很旧,很稳定,有一些文档记录,而且有点笨拙。但这是可以做到的。

或者您只需使用 RInside它为您做所有事情——并附带八 (8) 个不同的示例子目录,其中包含数十个已工作和正在运行的示例。这是其中一个(核心)(有点旧,我们现在可以写得更紧凑):

#include <RInside.h>                    // for the embedded R via RInside
#include <iomanip>

int main(int argc, char *argv[]) {

    RInside R(argc, argv);              // create an embedded R instance 

    std::string txt =                   // load library, run regression, create summary
        "suppressMessages(require(stats));"     
        "swisssum <- summary(lm(Fertility ~ . , data = swiss));" 
        "print(swisssum)";             
    R.parseEvalQ(txt);                  // eval command, no return

    // evaluate R expressions, and assign directly into Rcpp types
    Rcpp::NumericMatrix     M( (SEXP) R.parseEval("swcoef <- coef(swisssum)"));                 
    Rcpp::StringVector cnames( (SEXP) R.parseEval("colnames(swcoef)"));
    Rcpp::StringVector rnames( (SEXP) R.parseEval("rownames(swcoef)")); 

    std::cout << "\n\nAnd now from C++\n\n\t\t\t";
    for (int i=0; i<cnames.size(); i++) {
        std::cout << std::setw(11) << cnames[i] << "\t";
    }
    std::cout << std::endl;
    for (int i=0; i<rnames.size(); i++) {
        std::cout << std::setw(16) << rnames[i] << "\t";
        for (int j=0; j<cnames.size(); j++) {
            std::cout << std::setw(11) << M(i,j) << "\t";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;

    exit(0);
}

然后:

edd@max:~/git/rinside/inst/examples/standard(master)$ make rinside_sample3
ccache g++ -I/usr/share/R/include -I/usr/local/lib/R/site-library/Rcpp/include -I/usr/local/lib/R/site-library/RInside/include -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -g -O3 -Wall -pipe -Wno-unused -pedantic -Wall    rinside_sample3.cpp  -Wl,--export-dynamic -fopenmp  -L/usr/lib/R/lib -lR -lpcre -llzma -lbz2 -lz -lrt -ldl -lm  -lblas -llapack  -L/usr/local/lib/R/site-library/RInside/lib -lRInside -Wl,-rpath,/usr/local/lib/R/site-library/RInside/lib -o rinside_sample3
edd@max:~/git/rinside/inst/examples/standard(master)$ ./rinside_sample3 

Call:
lm(formula = Fertility ~ ., data = swiss)

Residuals:
     Min       1Q   Median       3Q      Max 
-15.2743  -5.2617   0.5032   4.1198  15.3213 

Coefficients:
                 Estimate Std. Error t value Pr(>|t|)    
(Intercept)      66.91518   10.70604   6.250 1.91e-07 ***
Agriculture      -0.17211    0.07030  -2.448  0.01873 *  
Examination      -0.25801    0.25388  -1.016  0.31546    
Education        -0.87094    0.18303  -4.758 2.43e-05 ***
Catholic          0.10412    0.03526   2.953  0.00519 ** 
Infant.Mortality  1.07705    0.38172   2.822  0.00734 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 7.165 on 41 degrees of freedom
Multiple R-squared:  0.7067,    Adjusted R-squared:  0.671 
F-statistic: 19.76 on 5 and 41 DF,  p-value: 5.594e-10



And now from C++

                           Estimate      Std. Error         t value        Pr(>|t|)
     (Intercept)            66.9152          10.706         6.25023     1.90605e-07
     Agriculture          -0.172114       0.0703039        -2.44814       0.0187272
     Examination          -0.258008        0.253878        -1.01627        0.315462
       Education           -0.87094        0.183029        -4.75849      2.4306e-05
        Catholic           0.104115       0.0352579         2.95297      0.00519008
Infant.Mortality            1.07705         0.38172         2.82157      0.00733572

edd@max:~/git/rinside/inst/examples/standard(master)$ 

这表明

  • 是的,我们可以在 C++ 中使用 R
  • 是的,我们可以让 R 报告结果
  • 是的,我们也可以让它们回到 C++

正如我所说,还有几十个例子。不,它不仅仅是神奇地将 R 编译成可执行文件——您需要安装 R 并调用它的共享库。

关于C++ 和 R : Create a . so 或 .dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35975927/

相关文章:

c++ - 在 QTreeview 特定单元格中添加 QCombobox

linux - 使用 --enable-compat15 编译 nfdump

c++ - Octave 标题缺失

c++ - g++4.8 处理 vector future 的问题

c++ - 正确使用GetLongPathName函数

c++ - Rcpp 数值 vector 输出只返回一个值

r - 大数据集清洗: How to fill in missing data based on multiple categories and searching by row order

c++ - 编译时的不同(空)结果

C++ 11 - 来自元组数组的数组元组

r - 如何在r中创建多个pivot_longer()列?