在R中,如何检查两个变量名是否引用相同的底层对象?

Zac*_*ach 19 r

例如:

A <- 1:10
B <- A
Run Code Online (Sandbox Code Playgroud)

A和B都引用相同的底层向量.

在我用C语言实现某些功能之前... R中是否有一个函数可以测试两个变量是否引用相同的底层对象?

谢谢.

Jos*_*ich 17

你可以使用这个.Internal inspect功能:

A <- 1:10
B <- A
.Internal(inspect(A))
# @27c0cc8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
.Internal(inspect(B))  # same
# @27c0cc8 13 INTSXP g0c4 [NAM(2)] (len=10, tl=0) 1,2,3,4,5,...
B[1] <- 21
.Internal(inspect(B))  # different
# @25a7528 14 REALSXP g0c6 [NAM(1)] (len=10, tl=150994944) 21,2,3,4,5,...
Run Code Online (Sandbox Code Playgroud)

Simon Urbanek编写了一个具有类似功能的简单包.这叫做......等待...... 检查.您可以通过运行以下命令从R-forge.net获取:

install.packages('inspect',repos='http://www.rforge.net/')
Run Code Online (Sandbox Code Playgroud)

更新:警告:

我建议你使用西蒙的包裹,因为我不建议你打电话.Internal.它当然不打算以交互方式使用,并且很可能通过不小心使用它来使R会话崩溃.

  • Oooooooh,我只是喜欢出现的内容?.内部:`只有真正的R向导才应该考虑使用这个函数,只有R开发人员可以添加到内部函数列表中.这句话很丰富.:)(当我可以投票时+1.) (3认同)
  • 是的,我已将我的`inspect`实现移植到核心R,我基本上只是维护它的R版本.由于`inspect`似乎仍在使用中,我可能会重新映射它以使用内部版本,但您可以安全地使用`.Internal(inspect(x))`.FWIW还有C级的"R_inspect"(在`gdb`中很有用). (3认同)
  • @Iterator:我喜欢假装成巫师.我有一顶帽子和一切.我也用剪刀跑. (2认同)

Ite*_*tor 16

您可以通过tracemem以下方式获取:如果它们指向相同的内存位置,则它们是相同的内存对象.

> a = 1:10
> b = a
> tracemem(a)
[1] "<0x00000000083885e8"
> tracemem(b)
[1] "<0x00000000083885e8"
> b = 1:10
> tracemem(b)
[1] "<0x00000000082691d0"
> 
Run Code Online (Sandbox Code Playgroud)

至于为什么知道它们是否是相同的对象是非常有用的:如果它们指向同一个对象并且存在延迟的评估/延迟评估/承诺,那么如果一个对象改变,则计算将在新的内存块时暂停被安排了.在某些情况下,延迟可能很大.如果有大对象,则等待很长时间,同时分配和复制大块内存.其他时候它可能只是一千次削减造成的死亡:这里和那里有很多小的扰动和延误.

更新(纳入约书亚的评论):一定要使用untracemem(),以免获得大量输出.你也可以看一下retracemem,虽然我还没有评论它的实用程序来设置跟踪.

  • 这是一个更安全的解决方案,但您可能希望在比较后`untracemem`,否则每次更改任何“跟踪”对象时都会通知您。 (2认同)