R的setnames:它如何检测链接对象?

时间:2016-05-26 11:38:42

标签: r attributes data.table pass-by-reference

R(setnames包)中的data.table函数对于R来说是不常见的,因为它通过引用更改输入,这意味着它不会复制其运行的表。 (不要与setNames包中的stats混淆。

这会产生令人惊讶(且不方便)的后果:它会更改先前保存names属性的任何对象。即:

require("data.table")

dt <- data.table(x = 1, y = 2)

dtnms <- function(dt){
    nms <- names(dt)
    print(nms)
    setnames(dt, c("a", "b"))
    nms
}

你会dtnms(dt)返回什么? "x" "y"当然。除非它没有 - setnames也修改了函数中的nms,因此在"x" "y"之前打印setnames时会返回"a" "b"。如果您在stop()之前放置setnames,则可以看到nms只是一个字符向量,没有特殊类别或其出处的其他指示。因此,我们希望setnames不知道nms来自何处,但不知何故链接是setnames到“看”的链接。这怎么可能? (这与简单的数据框相同)。

进一步观察(记得每次重置dt):

  1. 链接通过进一步的分配传播

    dtnms2 <- function(dt){
    nms <- names(dt)
        print(nms)
        nms2 <- nms
        setnames(dt, c("a", "b"))
        nms2
    }
    

    dtnms2(dt)提供"a" "b"

  2. 该链接不仅仅是一个相似性问题

    dtnms3 <- function(dt){
        chv <- c("x", "y")
        setnames(dt, c("a", "b"))
        chv
    }
    

    dtnms3(dt)提供"x" "y"

  3. identical

    无法检测到该链接
    dtnms4 <- function(dt){
        chv <- c("x", "y")
        nms <- names(dt)
        identical(chv, nms)
    }
    

    dtnms4(dt)提供TRUE

  4. 链接可以被破坏(这可能是解决此问题的最佳方式)

    dtnms5 <- function(dt){
        nms <- names(dt)
        nms <- paste(nms)
        setnames(dt, c("a", "b"))
        nms
    }
    

    dtnms5(dt)"x" "y"返回到预期值。 paste打破了链接,无论它是什么。

  5. 所以我的问题是,链接是什么?为什么setnames会更改nms对象,这只是一个普通的旧字符向量,不知道它来自哪里?

0 个答案:

没有答案