【问题标题】:R object identityR对象身份
【发布时间】:2012-06-10 09:08:46
【问题描述】:

有没有办法在 R 语言中测试两个对象是否相同?

为清楚起见:我的意思不是在 identical 函数的意义上相同, 它根据某些属性(如数值或逻辑值等)比较对象。

我对对象身份非常感兴趣,例如可以使用 Python 语言中的is 运算符对其进行测试。

【问题讨论】:

  • 对于那些不熟悉 Python 的人,你能详细说明你是如何定义身份的(或者说是相同的)吗?在严格意义上,一个对象只能与它自己相同。该测试的预期用途是什么?
  • 你是说对象类吗?例如is.numeric?
  • @Andrie 和 Roland:我的意思是主内存中相同地址的身份。例如,在 Python 或 Java 等通用语言中,我可以执行类似(模语法)b = new Object() c = b 在这种情况下,b 和 c 指向同一个对象。
  • @joran: 参考类可能会很有趣 (?getRefClass) ... ?

标签: r object identity


【解决方案1】:

您可以使用pryr 包。

例如返回mtcars对象的内存位置:

pryr::address(mtcars)

然后,对于变量ab,您可以检查:

address(a) == address(b)

【讨论】:

    【解决方案2】:

    更新address(x)(不使用.Internal(inspect(x)))的更强大和更快的实现已添加到data.table v1.8.9。来自NEWS

    新函数 address() 返回其参数在 RAM 中的地址。有时在确定值是否已被 R 以编程方式复制时很有用。


    可能有一种更简洁的方法,但这似乎可行。

    address = function(x) substring(capture.output(.Internal(inspect(x)))[1],2,17)
    x = 1
    y = 1
    z = x
    identical(x,y)
    # [1] TRUE
    identical(x,z)
    # [1] TRUE
    address(x)==address(y)
    # [1] FALSE
    address(x)==address(z)
    # [1] TRUE
    

    您可以通过将 17 更改为 9 来修改它以在 32 位上运行。

    【讨论】:

    • 这很有趣。你知道我可以在哪里阅读更多关于 R 何时实际创建新对象以及何时只指向内存中现有对象的信息吗?
    • @Roland 嗯。我认为搜索和找到一些链接会很容易,但似乎并非如此。我发现的只是section 1.1.2 of R Internals,它解释了按值调用错觉是如何实现的。我倾向于尝试使用tracemem.Internal(inspect(...)) 来确定何时制作副本。这样做会导致this post to r-devel,这可能会提供更多线索。
    • 是否可以逆向写address
    • @MatthewLundberg 嗯 ...我想在许多不同的环境中可能有许多符号都绑定到同一个地址。 可能。你心里有没有用?哦,但你的意思是创建一个到地址的绑定并取消引用它,就像 C 中的 *p 一样。那是不可能的(我猜)因为垃圾收集可能同时清除了该对象。
    • 确实,垃圾收集可能会在获取地址和调用反向地址之间获取对象。这可能会使程序崩溃,或者更糟的是,返回一个不相关的对象。因此,address 的反义词听起来是个非常糟糕的主意。
    猜你喜欢
    • 2018-09-07
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    • 2013-11-19
    • 2021-04-11
    • 2019-06-23
    • 2018-11-29
    相关资源
    最近更新 更多