Rcpp循环存储NumericMatrix到List时仅保留最终值的问题
问题产生原因
Rcpp 中 NumericMatrix 等对应R原生类型的对象,默认采用浅拷贝的赋值语义:当你直接将mat赋值给List的元素时,程序并不会复制矩阵存储的实际数值,只是在List中保存了一个指向mat所在内存地址的引用。
整个运行过程中你始终只操作了同一块内存里的矩阵数据,后续循环修改mat的数值时,所有List元素指向的同一块内存内容都会同步变化,最终所有List元素自然都会展示最后一次迭代结束后的矩阵值,无法保留各迭代阶段的快照。
修复方案
每次向List存储矩阵时,主动调用clone()方法对当前状态的矩阵做深拷贝,这个操作会完整复制当前矩阵的所有数值到独立的新内存块,后续修改原mat的操作不会影响已经存入List的副本。
你只需要把原代码中list(j) = mat;替换为list(j) = clone(mat);即可,修复后的完整代码如下:
#include <Rcpp.h> using namespace Rcpp; // [[Rcpp::export]] List updatingList(int n) { // 创建每次迭代会更新的NumericMatrix NumericMatrix mat(n, 2); for (int i=0; i < n; i++) { mat(i,0) = 0; // 初始Th1值 mat(i,1) = 1; // 初始Th2值 } // 创建用于存储每步矩阵的List List list(n); for (int j=0; j < n; j++) { // 深拷贝当前矩阵存入List list(j) = clone(mat); // 更新原矩阵数值 for (int i=0; i < n; i++) { mat(i,0) += 1; mat(i,1) += 1; } } return(list); } /*** R updatingList(3) */
修复后运行updatingList(3)将得到预期输出:
> updatingList(3) [[1]] [,1] [,2] [1,] 0 1 [2,] 0 1 [3,] 0 1 [[2]] [,1] [,2] [1,] 1 2 [2,] 1 2 [3,] 1 2 [[3]] [,1] [,2] [1,] 2 3 [2,] 2 3 [3,] 2 3
内容的提问来源于stack exchange,提问作者Clay Cressler
相关产品推荐
相关产品推荐

