如果您有一个data.frame
,其中不包含NA
s的因素,则可以无问题过滤数据。
set.seed(123)
df=data.frame(a = factor(as.character(c(1, 1, 2, 2, 3, NA,3,NA)),exclude=NULL),
b= runif(8))
#str(df)
df[df$a==3,]
# a b
# 5 3 0.9404673
# 7 3 0.5281055
如果您需要按NA级别过滤,则会出现问题。以下是不起作用的:
df[df$a==NA,]
df[df$a=="NA",]
df[is.na(df$a),]
我发现的唯一方法是将因子转换为数字并将其比较。
df[as.numeric(df$a)==4,]
# a b
#6 <NA> 0.0455565
#8 <NA> 0.8924190
还有其他更直观/优雅的方法来获得相同的结果吗?
检查相应df$a
的级别是否为Na:
df[is.na(levels(df$a)[df$a]),]
a b
6 <NA> 0.1649003
8 <NA> 0.6556045
正如弗兰克(Frank)指出的那样,这还包括观察值,其中df$a
的值(不仅是级别)是NA
。我想原始海报希望包括这些情况。如果没有,一个人可以做
x <- factor(c("A","B", NA), levels=c("A", NA), exclude = NULL)
i <- which(is.na(levels(x)[x]))
i[!is.na(x[i])]
给您3
,只有NA
级别,忽略未知级别(b)。
如果您也有真正的缺失值(不属于因素级别)...
DF = data.frame(
x = factor(c("A", "B", NA), levels=c("A", NA), exclude=NULL),
v = 1:3
)
第3行x
具有级别NA
,而第2行是一个真正的缺失值。
要获得第3行,您可以加入Data.Table ...
library(data.table)
setDT(DF)
merge(DF, data.table(x = factor(NA_character_, exclude=NULL)))
# or
DF[.(factor(NA_character_, exclude=NULL)), on=.(x), nomatch=0]
# x v
# 1: NA 3
或在dplyr中更尴尬:
dplyr::right_join(DF,
data.frame(x = factor(NA_character_, levels=levels(DF$x), exclude=NULL)))
# Joining, by = "x"
# x v
# 1 <NA> 3
除了疯狂...
,我找不到可以到达这里的方法wv = which(is.na(levels(DF$x)))
DF[ !is.na(DF$x) & as.integer(DF$x) == wv, ]
# x v
# 3 <NA> 3
我同意is.na()
对因素没有响应有些奇怪。但这似乎有效:
set.seed(123)
df=data.frame(a = factor(as.character(c(1, 1, 2, 2, 3, NA,3,NA)),exclude=NULL),
b= runif(8))
df[is.na(as.character(df$a)),]
dplyr的一种简单方法和%operator的%是:
df %>%
filter(
a %in% NA_character_
)
#> a b
#> 1 <NA> 0.0455565
#> 2 <NA> 0.8924190
正如这里提到的那样,在R中匹配的NA可能有点有趣。"%trick"的"%"提供更宽松的匹配,尽管恐怕我无法解释这些信息。