如何在R中对数据进行子集而不会丢失NA行?

时间:2016-11-06 05:02:43

标签: r dataframe subset na

我在R中看到了一些数据。一个标题为“Height”的特定列包含几行NA。

我希望对数据框进行子集化,以便从我的分析中排除高于某个值的所有高度。

df2 <- subset ( df1 , Height < 40 )

但是每当我这样做时,R会自动删除包含高度NA值的所有行。我不想要这个。我试过包含na.rm的参数

f1 <- function ( x , na.rm = FALSE ) {
df2 <- subset ( x , Height < 40 )
}
f1 ( df1 , na.rm = FALSE )

但这似乎没有做任何事情; NA的行仍然从我的数据框中消失。有没有一种方法可以对我的数据进行子集化,而不会丢失NA行?

3 个答案:

答案 0 :(得分:10)

如果我们决定使用subset功能,那么我们需要注意:

For ordinary vectors, the result is simply ‘x[subset & !is.na(subset)]’.

因此只保留非NA值。

如果您想保留NA个案例,请使用逻辑或条件告诉R不要删除NA个案例:

subset(df1, Height < 40 | is.na(Height))
# or `df1[df1$Height < 40 | is.na(df1$Height), ]`

不要直接使用(很快会解释):

df2 <- df1[df1$Height < 40, ]

示例

df1 <- data.frame(Height = c(NA, 2, 4, NA, 50, 60), y = 1:6)

subset(df1, Height < 40 | is.na(Height))

#  Height y
#1     NA 1
#2      2 2
#3      4 3
#4     NA 4

df1[df1$Height < 40, ]

#  Height  y
#1     NA NA
#2      2  2
#3      4  3
#4     NA NA

后者失败的原因是NA的索引编号为NA。考虑这个带有向量的简单示例:

x <- 1:4
ind <- c(NA, TRUE, NA, FALSE)
x[ind]
# [1] NA  2 NA

我们需要以某种方式将NA替换为TRUE。最直接的方法是添加另一个“或”条件is.na(ind)

x[ind | is.na(ind)]
# [1] 1 2 3

这正是您所处的情况。如果您的Height包含NA,则逻辑操作Height < 40最终会混合TRUE / FALSE / NA,因此我们需要替换{ {1}} NA如上所述。

答案 1 :(得分:1)

你也可以这样做:

df2 <- df1[(df1$Height < 40 | is.na(df1$Height)),]

答案 2 :(得分:0)

要通过字符/因子变量进行子集设置,可以使用%in%来保留NA。指定您要排除的数据。

# Create Dataset
library(data.table)
df=data.table(V1=c('Surface','Bottom',NA),V2=1:3)
df
#         V1 V2
# 1: Surface  1
# 2:  Bottom  2
# 3:    <NA>  3

# Keep all but 'Bottom'
df[!V1 %in% c('Bottom')]
#         V1 V2
# 1: Surface  1
# 2:    <NA>  3

之所以有效,是因为%in%从不返回NA(请参阅?match