簡體   English   中英

如何使用Rcpp將R對象傳遞給C ++?

[英]How to hand R objects to C++ using Rcpp?

如何使用Rcpp將R對象傳遞給C ++?

嘿,我是Rcpp的新手,並且遇到以下問題(這可能很簡單,但我無法弄清楚)。 我首先在R中創建一個列表,向量和一個數據框。我想將這些R對象傳遞給C ++來修改列表,然后將修改后的列表再次返回給R進行進一步分析。

我在Rstudio中制作了一個cpp文件的示例:

#include <Rcpp.h>
using namespace Rcpp;

/*** R
mylist <- list(mat1 = data.frame(Col1 = c('id1','id2','id3'), Col2 = c(5,6,7), Col3 = as.factor(c('blue','green','black'))),
               mat2 = data.frame(Col1 = c('id1','id2','id3'), Col2 = c(5,6,7), Col3 = as.factor(c('blue','green','black'))),
               mat3 = data.frame(Col1 = c('id1','id2','id3'), Col2 = c(5,6,7), Col3 = as.factor(c('blue','green','black'))),
               mat4 = data.frame(Col1 = c('id1','id2','id3'), Col2 = c(5,6,7), Col3 = as.factor(c('blue','green','black'))))
myvector1 <- c(seq(8,10,1))
myvector2 <- c(seq(101,103,1))

mydataframe <- data.frame(Col1 = c('id3','id4','id5'), Col2 = seq(21,23,1), Col3 = as.factor(c('blue','green','black')))
*/


// [[Rcpp::export]]

// Some code modifying mylist with myvector1, myvector2 and mydataframe and returning the modified list again to R
// Let's say Col2 of mat1 of mylist shall be multiplied with myvector1 and Col 2 of mat2 with myvector2. 
// Col2 of mat4 shall be divided by Col2 of mydataframe
// And then the modified mylist should be returned
}

/*** R
# Some analysis with the new modified list generated in the C++ code
summary(mylist$mat2$Col2)
*/

如何使這樣的操作正常工作(實際上,我的列表要大得多)? 還是將Rscript與cxxfunction函數一起使用會更好? 謝謝您的幫助!

看來您的問題是如何使用Rcpp 實際上結合R和C ++。 我看到幾種方法。 選擇哪種代碼取決於代碼量,您進行相似分析的頻率,將來再次需要進行此特定分析的可能性等。最好自己嘗試一下,以便您可以何時選擇自己的啟發式方法。

單文件

C ++加R

如果C ++比R多,那么使用一個帶有特殊R注釋的cpp會很有用。 總體結構:

#include <Rcpp.h>

// [[Rcpp::export]]
void foo(Rcpp::List l, Rcpp::NumericVector v1, Rcpp::NumericVector v2, Rcpp::DataFrame df) {
    Rcpp::List mat2 = l["mat2"];
    Rcpp::NumericVector Col2 = mat2["Col2"];
    Col2(0) = 10;
}

/*** R
mylist <- list(mat1 = data.frame(Col1 = c('id1','id2','id3'), Col2 = c(5,6,7), Col3 = as.factor(c('blue','green','black'))),
               mat2 = data.frame(Col1 = c('id1','id2','id3'), Col2 = c(5,6,7), Col3 = as.factor(c('blue','green','black'))),
               mat3 = data.frame(Col1 = c('id1','id2','id3'), Col2 = c(5,6,7), Col3 = as.factor(c('blue','green','black'))),
               mat4 = data.frame(Col1 = c('id1','id2','id3'), Col2 = c(5,6,7), Col3 = as.factor(c('blue','green','black'))))
myvector1 <- c(seq(8,10,1))
myvector2 <- c(seq(101,103,1))

mydataframe <- data.frame(Col1 = c('id3','id4','id5'), Col2 = seq(21,23,1), Col3 = as.factor(c('blue','green','black')))

foo(mylist, myvector1, myvector2, mydataframe)

summary(mylist$mat2$Col2)
*/

這與您所擁有的類似,但只有一個R注釋。 您需要調用Rcpp::sourceCpp("<file>")進行編譯並執行R注釋中的代碼。 在RStudio中,您可以使用“源”。

請注意,在上面的示例中,列表是通過引用更改的,這很危險,因為R遵循寫策略的副本。 對於大型列表,這當然很昂貴,這可能就是您正在尋找C ++解決方案的原因。

R加C ++

如果只有很少的C ++代碼,則可以使用Rcpp:cppFunction("<C++ code>") 我不會再使用inline::cxxfunction了。 我很少使用這種方法,因為沒有編輯器支持C ++代碼。

R Markdown

R Markdown允許您使用rrcpp塊以相等的基礎組合R和C ++。 如果要向分析添加一些散文,這將非常有用。 在RStudio中,您將獲得對兩種類型的塊的編輯器支持。 但是,有時來自C ++編譯器的錯誤消息會被弄亂,使它們更加難以解釋。

多個文件

項目

如果增加代碼量或輸入數據文件,則可以考慮某種項目結構,例如,數據文件的目錄dataRsrc ,具有函數定義的R腳本和C ++文件。 然后,驅動程序文件(R或RMD)將加載數據, source將R腳本和sourceCpp執行實際分析前的C ++文件。

R包

一旦使用了項目結構,您還可以打包。 僅需很少的額外工作,您就會獲得以下幾個優點:

  • C ++代碼只需要編譯一次
  • R函數立即進行字節編譯
  • C ++函數可以輕松地與並行處理一起使用
  • 清除結構以集成文檔和測試
  • ...

請注意,您可以從一個空包和一個Rmd文件開始。 一開始,您僅使用Rmd文件。 您可以不時地重構代碼,以將部分功能作為R或C ++函數移動到程序包中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM