gpt4 book ai didi

r - `c(1L, 2L, 3L)` 和 `1:3` 之间的修改时复制行为不同

转载 作者:行者123 更新时间:2023-12-03 17:30:10 26 4
gpt4 key购买 nike

我在看 Advanced R作者 Hadley Wickham,试图解决 exercise 2从第 2.3.6 节关于修改时复制:

Explain why tracemem() shows two copies when you run this code. Hint: carefully look at the difference between this code and the code shown earlier in the section.

x <- c(1L, 2L, 3L)
tracemem(x)

x[[3]] <- 4

(前面的代码将 double 列表中的一个元素更改为另一个 double ,仅产生一个副本。)
Advanced R Solutions作者 Grosser 和 Bumann they explain第二个副本是由于类型强制,从整数到 double 。他们没有定义 xc(1L, 2L, 3L) ,但使用 x <- 1:3 ,我认为这是等效的(使用 identical 比较它们也会返回 TRUE )。但是,运行上面的代码(在我这边)只会产生一个副本,但是运行以下代码会产生两个副本:
x <- 1:3
tracemem(x)

x[[3]] <- 4
运行此代码还会产生两个副本:
x <- c(1L, 2L, 3L)
typeof(x)
tracemem(x)

x[[3]] <- 4
例如替换 typeofclass只产生一份副本,但将其替换为 modepryr::otype产生两个副本。但只需打印 x out 而是产生一份副本。
那么 c(1L, 2L, 3L)有什么区别?和 1:3 ,为什么调用上述部分而不是全部函数会改变行为?
我使用 Rterm 从 PowerShell 运行代码时得到相同的行为并在 RStudio 的控制台中。

最佳答案

我在@brodieg 的博客 https://www.brodieg.com/2019/02/18/an-unofficial-reference-for-internal-inspect/#fn4 中找到了答案

与其使用 tracemem,不如使用 .Internal(inspect(x)) 深入了解

x <- c(1L, 6L, 10L)
.Internal(inspect(x))
#> @7fc0397e0f88 13 INTSXP g0c2 [NAM(1)] (len=3, tl=0) 1,6,10
x <- c(1L, 6L, 10L)
typeof(x)
.Internal(inspect(x))
#> @7fc0397e0f08 13 INTSXP g0c2 [NAM(7)] (len=3, tl=0) 1,6,10
.Internal(inspect(x))的返回值是一堆信息,但重要的是 NAM。 NAM 是引用计数器,一种确定有多少 R 对象指向相同底层事物的方法。这里 typeof()增加了它。 typeof()是一个闭包,闭包参数上的“NAM”值总是递增的。

每个@brodieg x 不会总是在为元素分配新值时被复制,但是当 NAM 引用计数启发式建议可能有多个对象引用时可能会被复制。

我找不到有关引用资料和 : 的任何信息, 但用它创建的对象自动具有引用计数 > 1
x <- 1:3
.Internal(inspect(x))
#> @7fc03bad6388 13 INTSXP g0c0 [NAM(7)] 1 : 3 (compact)

所以对于 x <- c(1L, 6L, 10L) 的原始情况,引用计数仅为 1,并且 R 启发式不会触发赋值的副本,但会触发类型强制。这就是为什么 tracemem只触发一次。

关于r - `c(1L, 2L, 3L)` 和 `1:3` 之间的修改时复制行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55713549/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com