【问题标题】:Subsetting R data frame results in mysterious NA rows子集 R 数据框导致神秘的 NA 行
【发布时间】:2012-12-25 01:24:25
【问题描述】:

我遇到了我认为是错误的问题。这没什么大不了的,但我很好奇是否有其他人看到过。不幸的是,我的数据是机密的,所以我必须举个例子,这不会很有帮助。

在对我的数据进行子集化时,我偶尔会得到原始数据框中没有的神秘 NA 行。甚至行名也是 NA。例如:

example <- data.frame("var1"=c("A", "B", "A"), "var2"=c("X", "Y", "Z"))
example

  var1 var2
1    A    X
2    B    Y
3    A    Z

然后我运行:

example[example$var1=="A",]

  var1 var2
1    A    X
3    A    Z
NA<NA> <NA>

当然,上面的例子实际上并没有给你这个神秘的 NA 行;我在此处添加它是为了说明我的数据遇到的问题。

也许这与我使用 Google's read.xlsx package 导入原始数据集,然后在子集之前执行宽到长整形有关。

谢谢

【问题讨论】:

  • 虽然没有看到您的数据就无法确定,但问题几乎可以肯定是您的某些索引大于数据中的行数。例如,使用上面的数据框尝试example[c(1, 2, 4),]example[c(TRUE, TRUE, FALSE, TRUE),]。检查用于子集行的向量的长度(如果是布尔值)和最大值(如果是数字)。
  • ...和/或您的一些索引本身是NA
  • 正如大卫所说,我们需要了解更多...但是查看str(yourdata)summary(yourdata) 会对您有很大帮助。我感觉您的var 列中至少有一个NA。测试它:example &lt;- data.frame("var1"=c("A", "B", "A", NA), "var2"=c("Q", "X", "Y", "Z")); example[example$var=='A',]
  • 如果您的代码类似于此示例(在您的专栏中采用d[d$v == x, ], your problem is indeed almost certainly NA`s 的形式。
  • 已答复!我在索引列中有 NA。我不敢相信我以前从未遇到过这种情况。有趣的是,当您在索引列中点击 NA 时,R 会使用 NA(甚至是行名!)“审查”其他列中的数据。我是在 StackOverflow 上发帖的新手,所以我需要花一点时间来弄清楚如何指定这个问题已回答。

标签: r subset reshape na


【解决方案1】:

将条件包裹在which:

df[which(df$number1 < df$number2), ]

工作原理:

它返回条件匹配的行号(条件为TRUE)并相应地对这些行上的数据框进行子集化。

这样说:

which(df$number1 < df$number2)

返回行号12345

因此,写作:

df[which(df$number1 < df$number2), ]

同写:

df[c(1, 2, 3, 4, 5), ]

或者更简单的版本是:

df[1:5, ]

【讨论】:

    【解决方案2】:

    我看到 OP 已经回答了这个问题,但由于他的评论深埋在评论部分,这是我解决这个问题的尝试(至少使用我的数据,它的行为方式相同)。

    首先,一些示例数据:

    > df <- data.frame(name = LETTERS[1:10], number1 = 1:10, number2 = c(10:3, NA, NA))
    > df
       name number1 number2
    1     A       1      10
    2     B       2       9
    3     C       3       8
    4     D       4       7
    5     E       5       6
    6     F       6       5
    7     G       7       4
    8     H       8       3
    9     I       9      NA
    10    J      10      NA
    

    现在是一个简单的过滤器:

    > df[df$number1 < df$number2, ]
         name number1 number2
    1       A       1      10
    2       B       2       9
    3       C       3       8
    4       D       4       7
    5       E       5       6
    NA   <NA>      NA      NA
    NA.1 <NA>      NA      NA
    

    这里的问题是第三列中NAs 的存在导致R 将整行重写为NA。尽管如此,数据框尺寸仍然保持不变。这是我的解决方法,它需要知道哪一列包含NAs:

    > df[df$number1 < df$number2 & !is.na(df$number2), ]
      name number1 number2
    1    A       1      10
    2    B       2       9
    3    C       3       8
    4    D       4       7
    5    E       5       6
    

    【讨论】:

    • 这就是我一直处理这个问题的方式,但是有没有办法将 !is.na 和
    • @Nova,我不这么认为,因为它们是两个不同的逻辑测试。不过,我很想被证明是错误的。
    • 上面已经回答了,which() 函数可能适合这个角色,但并不令人满意。我坚信这是一个错误恕我直言,不幸的是,这个“功能”(NA 选择疯狂)不会被修复。
    • 这对于理解为什么这种情况总是发生在我身上非常有帮助。我同意其他人的观点,这是一个错误。希望 R 核心团队中的某个人也同意。
    • @colin,我不太确定这是一个错误,现在我只是将其称为 R 背后的设计理念的结果,即默认情况下不丢弃 NA 值。相反,R 通常做的是“哦,这个向量上有一个 NA,所以我将把整个事情显示为 NA,因为我不知道 NA 的值代表什么以及它如何影响其余部分向量)。以mean(c(1, 3, NA))为例。R将打印NA,因为它不知道第三个值是什么,所以它不能真正告诉你平均值是什么。如果用户想要删除NA,他们必须明确设置na.rm=TRUE
    【解决方案3】:

    使用与您发布的代码类似的代码时,我遇到了同样的问题。使用函数子集()

    subset(example,example$var1=="A")
    

    NA 行反而被排除在外。

    【讨论】:

    • 这很有帮助,但请注意在交互式 R 会话之外的任何地方使用 subset 的潜在问题。来自函数的帮助页面:“这是一个旨在以交互方式使用的便利函数。对于编程,最好使用标准子集函数,例如 [,特别是参数子集的非标准评估可能会产生意想不到的后果。”跨度>
    【解决方案4】:

    使用 dplyr:

    library(dplyr)
    filter(df, number1 < number2)
    

    【讨论】:

    • 确实,图书馆没有遭受 NA 的困扰。
    【解决方案5】:

    我发现使用 %in$ 而不是 == 可以解决这个问题,尽管我仍然想知道为什么。 例如,而不是: df[df$num == 1,] 采用: df[df$num %in% c(1),] 会起作用。

    【讨论】:

    • 2020,在 R 3.6.3 中工作并使用 df[df$col1 %in% c("Whatever"), ] 给我带来一个没有空 NA 索引行的表。而像这样使用等号:df[df$col1 == "Whatever", ] 带回最初的问题。一个带有空行的过滤表,索引为 NA。
    【解决方案6】:
       > example <- data.frame("var1"=c("A", NA, "A"), "var2"=c("X", "Y", "Z"))
        > example
          var1 var2
        1    A    X
        2 <NA>    Y
        3    A    Z
        > example[example$var1=="A",]
           var1 var2
        1     A    X
        NA <NA> <NA>
        3     A    Z
    

    可能这一定是您期待的结果...试试这个 尝试在条件之前使用哪个条件来避免 NA 的

      example[which(example$var1=="A"),]
          var1 var2
        1    A    X
        3    A    Z
    

    【讨论】:

      【解决方案7】:

      另一个原因可能是条件错误,例如检查因子列是否等于不在其级别中的值。困扰了我一段时间。

      【讨论】:

      • 亲爱的反对者,请解释反对的原因,谢谢!
      猜你喜欢
      • 2015-08-28
      • 2021-03-24
      • 1970-01-01
      • 2012-04-10
      • 2018-11-24
      • 1970-01-01
      相关资源
      最近更新 更多