通过引用传递data.frame并使用rcpp更新它

通过引用传递data.frame并使用rcpp更新它,r,rcpp,R,Rcpp,查看图库中的rcpp文档和rcpp::DataFrame,我意识到我不知道如何通过引用修改数据帧。在谷歌上搜索一下,我发现这篇文章在SO上,这篇文章在档案中。 没有什么明显的东西,所以我怀疑我错过了一些重要的东西,比如“事情已经是这样了,因为”或者“它没有意义,因为” 我尝试了下面的编译,但是传递到R中的updateDFByRef的data.frame对象保持不变 #include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]]

查看图库中的
rcpp
文档和
rcpp::DataFrame
,我意识到我不知道如何通过引用修改数据帧。在谷歌上搜索一下,我发现这篇文章在SO上,这篇文章在档案中。 没有什么明显的东西,所以我怀疑我错过了一些重要的东西,比如“事情已经是这样了,因为”或者“它没有意义,因为”

我尝试了下面的编译,但是传递到R中的
updateDFByRef
data.frame
对象保持不变

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void updateDFByRef(DataFrame& df) {
    int N = df.nrows();
    NumericVector newCol(N,1.);
    df["newCol"] = newCol;
    return;
}
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
void updateDFByRef(数据帧和df){
int N=df.nrows();
数值向量newCol(N,1.);
df[“newCol”]=newCol;
返回;
}
简短的回答是“因为它毫无意义”

一个
data.frame
本质上是一个向量列表。几秒钟的思考清楚地表明,向该列表添加新列需要一个副本。因此,在本例中,您更改了变量df,但不返回它,因此失去了修改


仅仅希望某些东西以某种方式工作并不总是足够的。

当您这样做时,实现
DataFrame::operator[]
的方式实际上是复制的:

df["newCol"] = newCol;
要做你想做的事情,你需要考虑数据帧是什么,一个向量列表,有一定的属性。然后,您可以通过复制向量(指针,而不是其内容)从原始数据中获取数据

像这样的东西就行了。这是一个多一点的工作,但不是那么难

// [[Rcpp::export]]
List updateDFByRef(DataFrame& df, std::string name) {
    int nr = df.nrows(), nc= df.size() ;
    NumericVector newCol(nr,1.);
    List out(nc+1) ;
    CharacterVector onames = df.attr("names") ;
    CharacterVector names( nc + 1 ) ;
    for( int i=0; i<nc; i++) {
        out[i] = df[i] ;
        names[i] = onames[i] ;
    }
    out[nc] = newCol ;
    names[nc] = name ;
    out.attr("class") = df.attr("class") ;
    out.attr("row.names") = df.attr("row.names") ;
    out.attr("names") = names ;
    return out ;
}
/[[Rcpp::export]]
列表updateDFByRef(数据帧和df,std::字符串名称){
int nr=df.nrows(),nc=df.size();
数值向量newCol(nr,1.);
列出(nc+1);
CharacterVector onames=df.attr(“名称”);
字符向量名称(nc+1);

对于(int i=0;iYou已经发布到列表中了。为什么要在这里重新发布?因此,用
SEXP
替换
void
,例如
return df;
将起到作用?是的,SEXP、Rcpp::list或Rcpp::DataFrame中的任何一个都可以。当前似乎是作为列表返回的,因此我们似乎失去了它的数据。frame-ness。非常好。因此有你的l这是一个成名的小项目:将data.table扩展移植到Rcpp。但是请停止对Rcpp代码库进行毫无根据的假设:您在Rcpp中所陈述的内容仍然是错误的,这就是您的问题所在。如果您更愿意使用data.table,那就开始吧。当然!现在我将尝试只在我已经找到答案的情况下提问“我不会再做出毫无根据的假设了!”斯塔夸特·德克(与罗曼一起)写道Rcpp。如果他说你不能在Rcpp中做你想做的事,你最好把他的建议当作福音。请注意,他并没有说这件事不能完全完成——他是专门回答你问题的Rcpp性质的。非常感谢你,现在这更清楚了,我想我缺少了一些基本知识,比如
SEXP
已经被重新定义了引用。我将查看。目前我正在“准备”R中的
数据表
,添加了一个额外的列并在Rcpp中更新了它,所以没有副本(我想)完成了。这更好了,我理解这样做的风险,但这对我现在所做的很好。谢谢。你又一次大错特错了:我认为我缺少了基本知识,比如SEXP已经是参考资料。不是参考资料,而是指针。试着查一下SEXP中的最后一个字母代表什么。