子集 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 <- 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)
返回行号1
、2
、3
、4
和5
。
因此,写作:
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
这里的问题是第三列中NA
s 的存在导致R 将整行重写为NA
。尽管如此,数据框尺寸仍然保持不变。这是我的解决方法,它需要知道哪一列包含NA
s:
> 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 行的主要内容,如果未能解决你的问题,请参考以下文章