如何使用包含NA作为级别的因子过滤data.frame

时间:2017-09-25 18:52:09

标签: r dataframe filtering

如果您的data.frame因素不包含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))
#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

还有其他更直观/更优雅的方式来获得相同的结果吗?

4 个答案:

答案 0 :(得分:5)

检查相应df$a的级别是否为na:

df[is.na(levels(df$a)[df$a]),]
     a         b
6 <NA> 0.1649003
8 <NA> 0.6556045

正如弗兰克指出的那样,这还包括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,仅提供<video width="400" height="255" poster="placeholder.png" controls> <source src="videos/myvideo.mp4" type="video/mp4"> </video> 级别,但不包含未知级别(B)。

答案 1 :(得分:3)

如果你也有真正的缺失值(不属于因子的水平)......

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

答案 2 :(得分:1)

我同意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)),]

答案 3 :(得分:0)

使用 dplyr 和 %in% 运算符的简单方法是:

url = 'https://www1.hkex.com.hk/hkexwidget/data/getequityfilter?lang=eng&token=evLtsLsBNAUVTPxtGqVeG8QpVRBPNt2I8CbDELLpyZv%2bff8QFzdfZ6w1Za4TWSJ6&sort=5&order=0&qid=1627367921383&callback=jQuery35106295196366220494_1627367912871&_=1627367912873'
req = requests.get(url)
#now for the extraction:
target = req.text.split('jQuery35106295196366220494_1627367912871(')[1].split(')')[0]
#EDIT
target = req.text.split('(')[1].split(')')[0]
data = json.loads(target)
data

正如这里的人们所提到的,R 中的 NA 匹配可能有点有趣。 “%in% 技巧”提供了更宽松的匹配,但我恐怕无法解释其中的来龙去脉。