[英]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多,那么使用一個帶有特殊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 ++解決方案的原因。
如果只有很少的C ++代碼,則可以使用Rcpp:cppFunction("<C++ code>")
。 我不會再使用inline::cxxfunction
了。 我很少使用這種方法,因為沒有編輯器支持C ++代碼。
R Markdown允許您使用r
和rcpp
塊以相等的基礎組合R和C ++。 如果要向分析添加一些散文,這將非常有用。 在RStudio中,您將獲得對兩種類型的塊的編輯器支持。 但是,有時來自C ++編譯器的錯誤消息會被弄亂,使它們更加難以解釋。
如果增加代碼量或輸入數據文件,則可以考慮某種項目結構,例如,數據文件的目錄data
, R
和src
,具有函數定義的R腳本和C ++文件。 然后,驅動程序文件(R或RMD)將加載數據, source
將R腳本和sourceCpp
執行實際分析前的C ++文件。
一旦使用了項目結構,您還可以打包。 僅需很少的額外工作,您就會獲得以下幾個優點:
請注意,您可以從一個空包和一個Rmd文件開始。 一開始,您僅使用Rmd文件。 您可以不時地重構代碼,以將部分功能作為R或C ++函數移動到程序包中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.