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

时间:2013-03-31 15:36:48

标签: r rcpp

查看库中的rcpp文档和Rcpp::DataFrame,我意识到我不知道如何通过引用修改DataFrame。谷歌搜索了一下我在SO上找到了这篇文章,这篇文章在档案上。 没有什么明显的,所以我怀疑我会错过一些像“已经是这样的情况因为”或“因为它没有意义”这样的大事。

我尝试了以下编译但是传递给R中的data.frame的{​​{1}}对象保持不变

updateDFByRef

2 个答案:

答案 0 :(得分:12)

实现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 ;
}

这种方法存在一些问题。您的原始数据框和您创建的数据框共享相同的向量,因此可能会发生不好的事情。因此,只有在知道自己在做什么的情况下才能使用它。

答案 1 :(得分:3)

简短的回答是“因为没有意义”。

data.frame本质上是一个向量列表。几秒钟的反射清楚地表明,向该列表添加新列需要复制。因此,您在示例中更改了变量df,不要返回它,因此无法修改。

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