我有一个 NumericMatrix,其值在循环的每次迭代中都会更新。我想在每次迭代时将矩阵存储在列表中。下面的代码给出了一个最小的可重现示例。然而,当我在 R 中编译并运行它时,列表中的每个元素都与最终矩阵相同,而不是存储每个矩阵。为什么会出现这种情况,我该如何解决?这似乎是一个非常简单的问题,但我一直找不到解决方案。
示例代码:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List updatingList(int n) {
// Create a NumericMatrix that will be updated every step
NumericMatrix mat(n, 2);
for (int i=0; i < n; i++) { // set the initial state of the susceptible hosts
mat(i,0) = 0; // initial Th1
mat(i,1) = 1; // initial Th2
}
// create a List that will store mat every step
List list(n);
for (int j=0; j < n; j++) {
// store the value of mat
list(j) = mat;
// update mat
for (int i=0; i < n; i++) {
mat(i,0) += 1;
mat(i,1) += 1;
}
}
return(list);
}
/*** R
updatingList(3)
*/
输出示例:
> updatingList(3)
[[1]]
[,1] [,2]
[1,] 3 4
[2,] 3 4
[3,] 3 4
[[2]]
[,1] [,2]
[1,] 3 4
[2,] 3 4
[3,] 3 4
[[3]]
[,1] [,2]
[1,] 3 4
[2,] 3 4
[3,] 3 4
使用 R 几年后,您会熟悉“写时复制”习惯用法。实际上,您这里所拥有的只是矩阵的“一个”实例,因此您返回的内容始终是相同的。因为它是相同的矩阵。也就是说,(稍微)想一下,这是一个功能。 您想要的是将矩阵值“密封”起来。所以我们需要改变的只是一行:
// store a deep copy of mat
list(j) = clone(mat);
通过在每次循环运行时请求深层副本,您实际上可以根据需要获得不同的
实例。 输出
> Rcpp::sourceCpp("answer.cpp")
> 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
>