代码之家  ›  专栏  ›  技术社区  ›  moodymudskipper

当使用“cbind()”时,“相同”的输入会触发不同的行为:从一个短变量中找到行名并将其丢弃

  •  2
  • moodymudskipper  · 技术社区  · 5 年前

    以下操作运行良好:

    df1 <- data.frame(a= 1, b = 2) 
    cbind(df1, c=3:4)
    #>   a b c
    #> 1 1 2 3
    #> 2 1 2 4
    

    但是,如果我子集 df1 ,即使保持不变,我也会收到警告:

    df2 <- df1[1,]
    identical(df1, df2)
    #> [1] TRUE
    cbind(df2, c=3:4)
    #>   a b c
    #> 1 1 2 3
    #> 2 1 2 4
    

    data.frame中的警告(…,check.names=FALSE):从 短变量,已被丢弃

    我还没有设置任何行名,这些行名应该是相同的,发生了什么?

    1 回复  |  直到 5 年前
        1
  •  2
  •   moodymudskipper    5 年前

    identical() 默认情况下,并不总是能讲述全部故事:

    identical(df1, df2, attrib.as.set = FALSE)
    #> [1] FALSE
    

    此选项更严格地比较属性,但如果我们在这里查看它们,我们只能看到顺序上的差异,这不是我们将看到的观察到的行为的原因。

    attributes(df1)
    #> $names
    #> [1] "a" "b"
    #> 
    #> $class
    #> [1] "data.frame"
    #> 
    #> $row.names
    #> [1] 1
    attributes(df2)
    #> $names
    #> [1] "a" "b"
    #> 
    #> $row.names
    #> [1] 1
    #> 
    #> $class
    #> [1] "data.frame"
    

    我们可以尝试使用 row.names() 但这无济于事,但可以使用显示更多信息 .row_names_info() dput() :

    row.names(df1) # sneaky snake!
    #> [1] "1"
    row.names(df2)
    #> [1] "1"
    .row_names_info(df1)
    #> [1] -1
    .row_names_info(df2)
    #> [1] 1
    
    dput(df1)
    #> structure(list(a = 1, b = 2), class = "data.frame", row.names = c(NA, 
    #> -1L))
    dput(df2)
    #> structure(list(a = 1, b = 2), row.names = 1L, class = "data.frame")
    

    事实上, cbind.data.frame() 电话 data.frame() 它本身叫 .row_names_info() 并在触发警告之前测试其标志,以及 .row_names_info(df1) 为负,而 .row_names_info(df2) 是积极的。

    将行名设置为 NULL “重新初始化”row.names。

    row.names(df2) <- NULL
    cbind(df2, c=3:4)
    #>   a b c
    #> 1 1 2 3
    #> 2 1 2 4
    

    所以,警告的本质是说,我们试图回收一排排 data.frame 它有行名,因此必须忽略行名才能进行回收。如果行名真的不存在,则回收过程会悄无声息地进行。

    现在我们可以在这里讨论“没有行名”的定义和相关性。

    我知道这个答案并不能回答所有问题(不是所有的方法,也不是任何原因),但这就是我所拥有的一切!