Rcpp将一个向量复制到另一个向量

5

我刚开始接触Rcpp和C++编程,所以请原谅我问一些基础问题。代码中的cpp部分如下:

// test.cpp

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void testRun() {
   IntegerVector Grp1 = IntegerVector::create(1,2,3,4);
   IntegerVector Grp2 = IntegerVector::create(3,4,5,6);

   Rf_PrintValue(Grp1);
   Grp1 = Grp2;
   Rf_PrintValue(Grp1);
   Grp2[3] = Grp2[3]+1;
   Rf_PrintValue(Grp1);
}

当我运行testrun()函数时,会得到输出结果。
> Rcpp::sourceCpp('test.cpp')
> testRun()
[1] 1 2 3 4
[1] 3 4 5 6
[1] 3 4 5 7

当我将Gr2分配给Gr1,即使用Gr1 = Gr2时,改变Gr2中的元素会同时改变Gr1中的值。是否有一个IntegerVectors函数可以执行类似于Gr1 = Gr2的副本的操作,或者我应该使用循环来完成呢?谢谢!

2
你是不是指的是 Rcpp::clone(),就像这个回答中所提到的 http://stackoverflow.com/a/21282929/143305 以及其他回答? - Dirk Eddelbuettel
2个回答

9
如评论中所示,您可以使用


Grp1 = clone(Grp2) ;

但是这将创建一个新的 R 对象,然后将其分配给 Grp1,因此您需要支付一些内存分配费用,并且会丢弃一些可以使用的内存,即在以后的垃圾收集器工作中增加了更多的工作量。
您也可以使用 std::copy 重复使用来自 Grp1 的现有内存。
std::copy( Grp2.begin(), Grp2.end(), Grp1.begin() ) ;

另一种可能有点过头的方法是使用sapply。类似这样:

auto identity = [](double x){ return x; } ;
Grp1 = sapply( Grp2, identity );

但是,考虑到Rcpp无法对lambda函数进行sapply操作,您可能需要在函数外部定义identity,以便使用此方法。

inline double identity(double x){ 
    return x ;
}

FWIW,在Rcpp14Rcpp11中,您可以简单地执行:

Grp1 = import(Grp2) ;

1
目前发生的是指针常见错误。Grp1和Grp2都是指针,所以将它们中的一个设置为另一个意味着它们指向同一个数组(对一个数组所做的任何更改都会影响另一个数组)。一种解决方案是使用迭代器逐个复制所有值。这可以通过弹出所有值并将另一个IntegerVector中的所有元素推入已清空的IntegerVector中来完成。

1
弹出和推入操作会对Rcpp类型的性能产生显著影响,因为这意味着大量的数据分配等。 - Romain Francois

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接