12

查看rcpp文档和Rcpp::DataFrame图库中,我意识到我不知道如何通过引用来修改 DataFrame。谷歌搜索了一下,我在 SO 上找到了这篇文章,在存档上找到了这篇文章。没有什么明显的,所以我怀疑我错过了诸如“已经如此,因为”或“它没有意义,因为”之类的重要内容。

我尝试了以下编译但data.frame传递给 updateDFByRefR 的对象保持不变

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void updateDFByRef(DataFrame& df) {
    int N = df.nrows();
    NumericVector newCol(N,1.);
    df["newCol"] = newCol;
    return;
}
4

2 回答 2

14

当您这样做时,实现的方式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 ;
}

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

于 2013-04-01T17:00:35.537 回答
2

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

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

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

于 2013-03-31T15:46:20.613 回答