1

所以我正在使用 R6(我的老板偏好)在 R 中编写一个程序。它必须做一些繁重的数字运算,所以我试图让 R6 类中的关键变量就地修改。不幸的是,在普通 R 中使变量修改到位的方法似乎在 R6 类中不起作用。我在下面构建了一个最小的示例。您可以清楚地看到 R6 类内部的变量,该变量在函数之后跳转到新的内存地址。在 R6 类之外,做完全相同的事情不会导致复制。任何人都可以就我为什么以及如何让类中的变量修改到位给我任何建议吗?

my_r6 <- R6Class("my_r6",
  public = list(
    test = function() {
      for (i in 1:5) {
        private$x$a[i] <- 3
      }
    }
  ),
  private = list(
    x = list(a = c(1, 2, 3, 4, 5))
  )
)
temp_r6 <- my_r6$new()
tracemem(temp_r6$.__enclos_env__$private$x$a)
temp_r6$test()
y <- list(b = c(1, 2, 3, 4, 5))
tracemem(y$b)
for (i in 1:5) {
  y$b[i] <- 3
}
4

1 回答 1

0

您的代码没有测试您的想法。tracemem()不会告诉您对象是否已就地修改。的详细信息部分?tracemem说它告诉您是否duplicate()已调用 C 函数。

并且(仅?)当多个名称/符号引用相同的数据时会发生这种情况。例如:

y <- list(b=1:5)
tracemem(y)
# [1] "<0000000009226B08>"
y[1] <- pi/2  # nothing else points to the same memory as 'y'
z <- y        # now 'z' and 'y' point to the same memory
z[1] <- pi    # this requires duplication of y
# tracemem[0x0000000009226b08 -> 0x00000000092228c8]:

此外,您在 R6 类之外的代码与其内部的代码不同。该private对象是一个环境,因此下面进行了更准确的比较。您可以看到它显示与 R6 代码相同的重复项。

e <- new.env()
e$y <- list(b = c(1, 2, 3, 4, 5))
tracemem(e$y$b)
for (i in 1:5) {
  e$y$b[i] <- 3
}
# tracemem[0x0000000008ff9c78 -> 0x000000000dac2298]:

我不会花时间调查或解释重复发生的原因或避免重复的方法,以防万一这是一个XY 问题。让我知道这是否非常接近您的实际问题,我会尝试通过编辑来回答。

于 2018-04-11T22:18:00.697 回答