【问题标题】:Passing by reference a data.frame and updating it with rcpp通过引用传递 data.frame 并使用 rcpp 更新它
【发布时间】:2013-03-31 15:36:47
【问题描述】:

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

我尝试了以下编译但 data.frame 对象在 R 中传递给 updateDFByRef 保持不变

#include <Rcpp.h>
using namespace Rcpp;

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

【问题讨论】:

  • 您已经发布到列表中。为什么要在这里转发?

标签: r rcpp


【解决方案1】:

当你这样做时,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 ;
}

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

【讨论】:

  • 非常感谢,现在更清楚了,我想我缺少基本知识,例如 SEXP 已经是参考。我去cran.r-project.org/doc/manuals/r-release/R-ints.pdf看看。现在我正在“准备”R中的data.table添加一个额外的列并在Rcpp中更新它,所以没有复制(我认为)。这好多了,我理解这样做的风险,但这对我正在做的事情来说很好。谢谢美人。
  • 再一次,你完全错了:我认为我缺少一些基本知识,比如 SEXP 已经是参考。不是引用,而是指针。尝试查找 SEXP 中的最后一个字母代表什么。
【解决方案2】:

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

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

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

【讨论】:

  • 所以用SEXP 替换void 例如return df; 就可以了?
  • 是的,任何 SEXP、Rcpp::List 或 Rcpp::DataFrame 都可以。目前似乎以列表的形式返回,所以我们似乎失去了它的 data.frame-ness。
  • 非常好。因此,您有一个小项目要出名:将 data.table 扩展移植到 Rcpp。但是请不要再对 Rcpp 代码库做出毫无根据的假设:您所说的在 Rcpp 中仍然是错误的,这就是您的问题所在。如果您更愿意使用 data.table,那就去吧。
  • 当然!到现在为止,我会尽量只在我已经找到答案的情况下提出问题,这样我就不会再做出毫无根据的假设了!
  • @statquant Dirk (与 Romain 一起)写了 Rcpp。如果他说你不能在 Rcpp 中做你想做的事,你最好把他的建议当作福音。请注意,他并没有说无法完成句号-他是专门针对您问题的Rcpp性质的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
相关资源
最近更新 更多