【r<-探索】R对象的名字与值——存储机制图解
2019-01-12 本文已影响9人
王诗翔
了解R是如何存储数据的将对R的机制、性能的理解亦或是代码的优化都有帮助。
绑定(binding)与 引用(reference)
将c(1, 2, 3)
赋值给变量x
时,实际上是将数值向量绑定到x
上的过程,变量x
称为引用。
当我们将变量x
重新赋值给y
时,实际上是为数值向量创建一个新的引用。
y <- x
我们可以验证一下,查看两个变量的内存地址:
obj_addr(x)
#> [1] "0x3000ed8"
obj_addr(y)
#> [1] "0x3000ed8"
(函数都来自lobstr包)
复制-修改(Copy-on-modify)
如果这时候对变量y
进行修改,引用y
将会指向新的数据(新的内存地址)。
x <- c(1, 2, 3)
y <- x
y[[3]] <- 4
x
#> [1] 1 2 3
列表
列表存储的是数值引用的引用。
l1 <- list(1, 2, 3)
重新赋值给新的变量,也是创建一个引用。
当对列表l2
进行修改时,有意思的地方来了:下面l2
只是将第3个元素的引用指向新的数值。
l2[[3]] <- 4
数据框
数据框本质上都是向量列表,现有下面数据框:
d1 <- data.frame(x = c(1, 5, 6), y = c(2, 4, 3))
如果修改其中一列,那么只会修改该列的引用,其他的列不会变更!
d2 <- d1
d2[, 2] <- d2[, 2] * 2
然而,如果我们修改一行,那么所有的都会变!
d3 <- d1
d3[1, ] <- d3[1, ] * 3
字符串向量
字符串向量也使用引用。
x <- c("a", "a", "abc", "d")
不过R这里会使用一个全局字符串池,字符串向量的每一个元素实际上是池中唯一字符串的一个指针。
以上内容整理自《Advanced R》