在R6类中强制修改(在R中)

时间:2018-04-11 14:29:24

标签: r r6

所以我使用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
}

1 个答案:

答案 0 :(得分:0)

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

当多个名称/符号引用相同数据时,会发生(仅?)。例如:

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 problem。如果这与您的实际问题非常接近,请告诉我,我会尝试使用编辑进行回答。