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

我遇到了一个我认为是窃听器的东西。没什么大不了的,但我很好奇是否有其他人看过这个。不幸的是,我的数据是保密的,所以我不得不捏造一个例子,它不会有很大的帮助。

当子集我的数据,我偶尔得到神秘的 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 的 read.xlsx 软件包导入我的原始数据集,然后在子集之前执行从宽到长的重塑有关。

谢谢

46434 次浏览

我在使用类似于您发布的代码时遇到了同样的问题

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

戒毒会被排除在外。

我看到 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导致 R 将整行重写为 NA。尽管如此,还是维护了数据框架的维度。下面是我的解决方案,它需要知道哪一列包含 NA:

> 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

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, ]

另一个原因可能是条件错误,比如检查 factor 列是否等于其级别之外的值。曾经困扰过我一段时间。

   > 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

使用 dplyr:

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

我发现在 $中使用% 而不是 = = 可以解决这个问题,尽管我仍然想知道为什么。 例如: Df [ df $num = = 1,] 用途: Df [% c (1)中的 df $num% ]将工作。