Rcpp,使函数可用于DLL中的R

时间:2018-11-03 21:50:14

标签: c++ r rcpp

C ++的新手,我想在R中提供在DLL中编译的函数。

到目前为止,对于Visual Studio中的these steps,然后从R使用integer来加载{创建的dll。

但是,我的C ++函数将需要处理R dyn.load个对象,但我不确定如何实现这一点。我从the Rcpp gallery看到data.frame可能在R和c ++数据类型(包括Rcpp对象)之间进行了某种转换,但我不知道是否可以使用{{1 }},然后可以使用data.frame将其包含在R中。

this answer by Dirk Eddelbuettel中,似乎可以使用Rcpp生成“动态库”,但是,当我尝试使用源dyn.load文件生成软件包时,找不到任何dll。使用Rcpp。我想使用dll的功能来自the Rcpp gallery

.cpp

我试图将代码粘贴到VisualStudio中以尝试生成该DLL,但是我有我很期待的错误“找不到Rcpp.h”。

然后我在RStudio中遵循以下步骤:

  1. 创建新项目/程序包
  2. 将此cpp源文件包含为该软件包的源文件
  3. rcpp.package.skeleton() Rcpp并输入#include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] DataFrame modifyDataFrame(DataFrame df) { // access the columns IntegerVector a = df["a"]; CharacterVector b = df["b"]; // make some changes a[2] = 42; b[1] = "foo"; // return a new data frame return DataFrame::create(_["a"]= a, _["b"]= b); } ,到目前为止,软件包文件夹中没有DLL
  4. 试图通过转到“构建/安装并重新启动”在RStudio中构建软件包,但是随后出现错误消息“正在构建R软件包需要安装其他构建工具,您是否要安装它们?”但是,我已经安装了RbuildTools 3.4,并且在RStudio中单击“是”时,没有任何反应。

PS:很高兴听到其他方法,但是如果可能的话,这里应该使用DLL格式。由于我基本上不了解Rcpp或C ++的工作原理,因此非常感谢任何信息

2 个答案:

答案 0 :(得分:2)

您需要弄清楚设置的原因。这很容易,而且很容易。观看:

R> Rcpp::cppFunction('DataFrame modDF(DataFrame df) { IntegerVector a = df["a"]; CharacterVector b = df["b"]; a[2] = 42; b[1] = "foo"; return DataFrame::create(Named("a")=a, Named("b")=b); } ')                  
R> df <- data.frame(a=1:3, b=letters[24:26])                                                                                                                                                                       
R> df                                                                                                                                                                                                              
  a b                                                                                                                                                                                                              
1 1 x                                                                                                                                                                                                              
2 2 y                                                                                                                                                                                                              
3 3 z                                                                                                                                                                                                              
R> modDF(df)                                                                                                                                                                                                       
   a   b                                                                                                                                                                                                           
1  1   x                                                                                                                                                                                                           
2  2 foo                                                                                                                                                                                                           
3 42   z                                                                                                                                                                                                           
R>      

现在,我显然不建议长时间使用这种格式编写。 您已经在正确的位置设置程序包。但是您需要弄清楚是什么阻碍了您的工具。

作为PS,上面的单线压痕更好:

R> Rcpp::cppFunction('DataFrame modDF(DataFrame df) { \
      IntegerVector a = df["a"]; \
      CharacterVector b = df["b"]; \
      a[2] = 42;  \
      b[1] = "foo"; \ 
      return DataFrame::create(Named("a")=a, Named("b")=b); \
    } ')                  

答案 1 :(得分:0)

以下似乎有效:

  1. 从R运行Rcpp.package.skeleton("dfcpp4", cpp_files="modifyDataFrame.cpp")。为了使modifyDataFrame使用dll可以使用dyn.load函数,需要第二个参数。
  2. 从命令行运行R CMD build dfcpp4
  3. 从命令行运行R CMD check dfcpp4 --no-manual
  4. dll文件现在位于src-x64文件夹中

我现在可以使用

调用此函数
dyn.load("dfcpp4/src-x64/dfcpp4.dll")
df <- data.frame(a = c(1, 2, 3),
                 b = c("x", "y", "z"))
.Call("_dfcpp4_modifyDataFrame", df)
   a   b
1  1   x
2  2 foo
3 42   z

我不明白的是为什么在这种情况下应该使用.Call而不是.C ...