如何在不丢失 NA 行的情况下对 R 中的数据进行子集化?
How to subset data in R without losing NA rows?
我在 R 中查看了一些数据。标题为 "Height" 的特定列包含几行 NA。
我希望对 data-frame 进行子集化,以便将所有高于特定值的高度排除在我的分析之外。
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 的行最终还是从我的 data-frame 中消失了。有没有办法在不丢失 NA 行的情况下对我的数据进行子集化?
如果我们决定使用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
。最直接的方法是添加另一个 "or" 条件 is.na(ind)
:
x[ind | is.na(ind)]
# [1] 1 2 3
这正是您的情况。如果您的 Height
包含 NA
,那么逻辑运算 Height < 40
最终会混合 TRUE
/ FALSE
/ NA
,因此我们需要替换 NA
通过 TRUE
如上所述。
您还可以这样做:
df2 <- df1[(df1$Height < 40 | is.na(df1$Height)),]
要通过 character/factor 个变量进行子集化,您可以使用 %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%
从来没有 returns NA
(参见 ?match
)
我在 R 中查看了一些数据。标题为 "Height" 的特定列包含几行 NA。
我希望对 data-frame 进行子集化,以便将所有高于特定值的高度排除在我的分析之外。
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 的行最终还是从我的 data-frame 中消失了。有没有办法在不丢失 NA 行的情况下对我的数据进行子集化?
如果我们决定使用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
。最直接的方法是添加另一个 "or" 条件 is.na(ind)
:
x[ind | is.na(ind)]
# [1] 1 2 3
这正是您的情况。如果您的 Height
包含 NA
,那么逻辑运算 Height < 40
最终会混合 TRUE
/ FALSE
/ NA
,因此我们需要替换 NA
通过 TRUE
如上所述。
您还可以这样做:
df2 <- df1[(df1$Height < 40 | is.na(df1$Height)),]
要通过 character/factor 个变量进行子集化,您可以使用 %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%
从来没有 returns NA
(参见 ?match
)