【问题标题】:Simplest way to create an exact copy of a vector in R?在 R 中创建向量的精确副本的最简单方法?
【发布时间】:2018-03-03 07:12:54
【问题描述】:

我正在尝试在 R 中创建一个向量的副本...我们称之为list_foo

我想创建另一个名为list_bar 的列表,它是list_foo 的精确副本,具有所有相同的元素和长度。在 R 中执行此操作的最简单方法是什么?

首选不导入库的解决方案。

【问题讨论】:

  • list_bar <- list_foo?
  • @DamianoFantini 不复制任何东西,它们都引用内存中的同一个对象x = c(1, 2, 3); y = x; pryr::address(x) == pryr::address(y)
  • @ScottWarchal 正确,除非您修改其中一个对象...我在回答中提到了这一点。不过,我认为你没有理由担心这一点,因为 R 可以很好地处理更新内存中的对象的问题......

标签: arrays r list vector copy


【解决方案1】:

R 不像 Python,其中变量名实际上是指向对象的指针。

在 Python 中,您需要您不喜欢的其他库(例如 copy)。在R 中,您可以这样做并创建一个名为list_bar 的新对象:

list_bar <- list_foo

【讨论】:

  • 除非你修改其中一个,否则它们是同一个对象。
【解决方案2】:

正如 Ken 的回答和我的评论中所指出的,我认为 99% 的 R 社区会建议您使用 &lt;- 运算符。但是,关于这 2 个对象在内存中的位置的注释是正确的。

library(pryr)
x <- c(1, 2, 3) 
y <- x
pryr::address(x) == pryr::address(y) #true
pryr::address(x)
# [1] "0x5832a668"

现在,如果你修改其中一个会发生什么?

x <- "hello world"
x
# [1] "hello world" # updated x, new location in the memory
pryr::address(x)
# [1] "0xa72aab88"
y
# [1] 1 2 3 #still the same
pryr::address(y)
# [1] "0x5832a668"

R 负责处理对象的存储位置,并自动为更新的对象创建一个新位置。所以你不必担心。你真的想要一个副本,即使 R 可以自己解决这个问题?如果是这样(并且如果您的对象是向量),您可以使用 sapply 例如(或 lapply 用于列表,或更复杂的方法用于其他类型的结构)。

# the 'y' object
y
# [1] 1 2 3
pryr::address(y)
# [1] "0x7d10bf68"

# let's create a copy of 'y' using sapply()
x <- sapply(y, function(i) i)  

# same vector, different location in the memory
pryr::address(x)
# [1] "0x5a8755b0"

# are they really identical? Yes
identical(x, y)  
# [1] TRUE

但是,我看不出你真的不想利用 x &lt;- y 的理由。就是这么简单!

【讨论】:

  • 一个可能的优势是当您将 GraalVM 与 FastR 结合使用时。当您使用 java 调用 RScript 时,x &lt;- y 成为引用复制,而不是 R 通常所做的。因此,需要强制复制才能使代码在 GraalVM 中运行
猜你喜欢
  • 1970-01-01
  • 2010-11-17
  • 2016-02-13
  • 2017-08-12
  • 2017-12-11
  • 2015-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多