Rcpp 中动态更新的列表仅存储最后一个值

问题描述 投票:0回答:1

我有一个 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 list loops rcpp
1个回答
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 >

© www.soinside.com 2019 - 2024. All rights reserved.