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