R-如何通过包含Na AS级别的因素过滤数据



如果您有一个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"的"%"提供更宽松的匹配,尽管恐怕我无法解释这些信息。

最新更新