【问题标题】:Weird NA behaviour in RR中奇怪的NA行为
【发布时间】:2013-12-21 12:08:02
【问题描述】:

在 R 中合并数据帧时,我注意到一些奇怪的行为。

合并时,我在合并的数据框中得到额外的 NA 行。如果显示数据框,则不会出现,并且不会影响 length() 的输出,但在索引时会变得明显。有一种解决方法,但并不是特别令人满意。我宁愿根本没有这种奇怪的行为。

使用 plyr 包中的join() 会发生这种情况,并且在使用 RODBC 连接 sql 查询中的表时也可能发生这种情况。其他软件包也可能发生这种情况。

谁能解释这里发生了什么以及如何避免它?我在 winXP 和 win8 中使用 RStudio,R 版本 3.0.1。

> library(plyr)
> # example adapted from http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
> 
> a <- as.data.frame(cbind(seq(1, 4, 1), c("Pirate", "Monkey", "Ninja", "Spaghetti")), stringsAsFactors = FALSE)
> names(a) <- c("a.id", "name")
> a
  a.id      name
1    1    Pirate
2    2    Monkey
3    3     Ninja
4    4 Spaghetti
> 
> b <- as.data.frame(cbind(seq(1, 5, 1), c("Pirate", "Rutabaga", "Darth Vader", "Ninja", "Ninja")), stringsAsFactors = FALSE)
> names(b) <- c("b.id", "name")
> b
  b.id        name
1    1      Pirate
2    2    Rutabaga
3    3 Darth Vader
4    4       Ninja
5    5       Ninja
> 
> z <- join(a, b, by = "name", type = "left", match = "all")
> z
  a.id      name b.id
1    1    Pirate    1
2    2    Monkey <NA>
3    3     Ninja    4
4    3     Ninja    5
5    4 Spaghetti <NA>
> z$compare <- ifelse(z$a.id==z$b.id, 1, 0)
> z # shows dataframe of 5 rows
  a.id      name b.id compare
1    1    Pirate    1       1
2    2    Monkey <NA>      NA
3    3     Ninja    4       0
4    3     Ninja    5       0
5    4 Spaghetti <NA>      NA
> z[z$compare==0 ,] # shows extra rows with row names of NA and NA.1
     a.id  name b.id compare
NA   <NA>  <NA> <NA>      NA
3       3 Ninja    4       0
4       3 Ninja    5       0
NA.1 <NA>  <NA> <NA>      NA
> 
> z <- z[!is.na(z$a.id),]
> z[z$compare==0 ,] # NA rows retained
     a.id  name b.id compare
NA   <NA>  <NA> <NA>      NA
3       3 Ninja    4       0
4       3 Ninja    5       0
NA.1 <NA>  <NA> <NA>      NA

# work around to produce expected output
> z[z$compare==0 & !is.na(z$compare) ,]
  a.id  name b.id compare
3    3 Ninja    4       0
4    3 Ninja    5       0

【问题讨论】:

    标签: r


    【解决方案1】:

    如果要提取compare 等于0 的行,则必须排除NA 情况。

    看看专栏compare

    z$compare
    [1]  1 NA  0  0 NA
    

    当您使用比较时,即==NAs 将导致NAs。 @Codoremifa 在他的回答中也表明了这一点。

    z$compare == 0
    # [1] FALSE    NA  TRUE  TRUE    NA
    

    您应该同时进行 (a) 比较 compare0 并排除 NAs 和 !is.na()

    z$compare == 0 & !is.na(z$compare)
    # [1] FALSE FALSE  TRUE  TRUE FALSE
    

    此命令仅返回 TRUEFALSE

    此输出可用于子集:

    z[z$compare == 0 & !is.na(z$compare), ]
    #   a.id  name b.id compare
    # 3    3 Ninja    4       0
    # 4    3 Ninja    5       0
    

    关于NA 用于索引数据帧行的行为。

    如果您使用NA 进行索引,所有值都将替换为NA

    z[NA, ]
    #      a.id name b.id compare
    # NA   <NA> <NA> <NA>      NA
    # NA.1 <NA> <NA> <NA>      NA
    # NA.2 <NA> <NA> <NA>      NA
    # NA.3 <NA> <NA> <NA>      NA
    # NA.4 <NA> <NA> <NA>      NA
    

    (此行为是由于矢量回收。命令与z[rep(NA, nrow(z)), ]相同。)

    如果您使用包含NAs 的索引向量,则相应的行也将仅包含NAs。

    例如:

    z[c(TRUE, NA, FALSE, NA, TRUE), ]
    #      a.id      name b.id compare
    # 1       1    Pirate    1       1
    # NA   <NA>      <NA> <NA>      NA
    # NA.1 <NA>      <NA> <NA>      NA
    # 5       4 Spaghetti <NA>      NA
    

    正如预期的那样,此命令返回第一行和第五行,以及与索引向量中的NAs 对应的两个NA 行。

    【讨论】:

    • 好的,我想我知道了,非常感谢您的回答。 z[z$compare == 0] 返回 NA 行,因为 NA == 0 本身既不是真也不是假,但实际上是 NA。
    【解决方案2】:

    您的行子集条件返回一个既不是 TRUE 也不是 FALSE 的 NA。 NA 行是指 data.frame 的第二行和第五行。

    例如-

    > z$compare==0
    [1] FALSE    NA  TRUE  TRUE    NA
    > z[NA,]
         a.id name b.id compare
    NA   <NA> <NA> <NA>      NA
    NA.1 <NA> <NA> <NA>      NA
    NA.2 <NA> <NA> <NA>      NA
    NA.3 <NA> <NA> <NA>      NA
    NA.4 <NA> <NA> <NA>      NA
    

    【讨论】:

    • 谢谢。第二和第四还是第二和第五? NA 行在 R 中是否有用?
    • @user2633645 NA 行不对应于数据框中的任何行。如果您使用NA 进行索引,则输出中的所有值都将替换为NA。看看,例如,a[NA, ]
    • @SvenHohenstein 好的,这是有道理的; a[NA] 在四行中返回 NA 并且 b[NA] 在五行中返回 NA ,这是根据您的解释所期望的。但是,为什么在 z[z$compare==0, ] 上建立索引时,会得到 NA 行?
    • @user2633645,第二和第五。,对不起。 NA 上的索引类似于z[NA,] 示例。您可以将其视为 R 不知道如何处理 z$compare==0 向量中的这两个 NA。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 2017-10-07
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多