子集 R 数据框导致神秘的 NA 行

Posted

技术标签:

【中文标题】子集 R 数据框导致神秘的 NA 行【英文标题】:Subsetting R data frame results in mysterious NA rows 【发布时间】: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(甚至是行名!)“审查”其他列中的数据。我是在 *** 上发帖的新手,所以我需要花一点时间来弄清楚如何指定这个问题已回答。 【参考方案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】:

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

【讨论】:

亲爱的反对者,请解释反对的原因,谢谢!

以上是关于子集 R 数据框导致神秘的 NA 行的主要内容,如果未能解决你的问题,请参考以下文章

子集数据框时选择了未定义的列

如何按名称选择列的子集来计算 R 中的行均值? [复制]

如何对您的数据框进行子集化以在 R 中保留前 3 个重复行?

R语言中怎么提取时间序列数据框中符合行名称的子集

一列中相同值的R子集行取决于另一列中的多个值

R:基于多个条件的两个数据帧的子集