在R中使用自动数据集搞乱了.
如果我运行以下内容:
auto = read.csv("Auto.csv", header=TRUE, na.strings="?")
summary(complete.cases(auto))
Run Code Online (Sandbox Code Playgroud)
我得到以下内容:
Mode FALSE TRUE NA's
logical 5 392 0
Run Code Online (Sandbox Code Playgroud)
但是,当我运行它时,我会得到不同的结果:
auto1 = na.omit(auto)
dim(auto) # returns [1] 397 9
dim(auto1) # returns [1] 392 9
Run Code Online (Sandbox Code Playgroud)
为什么complete.cases()告诉我我没有NA,但na.omit()似乎删除了一些条目?
不同之处在于complete.cases返回与数据集的行数相同长度的逻辑向量,同时na.omit删除具有至少一个NA的行.使用下面创建的可重现示例,
complete.cases(auto)
#[1] TRUE FALSE TRUE TRUE TRUE TRUE FALSE FALSE TRUE FALSE
Run Code Online (Sandbox Code Playgroud)
我们可以看到,它是一个没有NA的逻辑向量.它给出TRUE了没有任何NA的行.因此,显然,summary对逻辑向量进行操作不会返回NA.
summary(complete.cases(auto))
# Mode FALSE TRUE NA's
#logical 4 6 0
Run Code Online (Sandbox Code Playgroud)
假设,我们需要得到相同的结果na.omit,导出的逻辑向量应该用于原始数据集的子集
autoN <- auto[complete.cases(auto),]
auto1 <- na.omit(auto)
dim(autoN)
#[1] 6 2
dim(auto1)
#[1] 6 2
Run Code Online (Sandbox Code Playgroud)
虽然,结果会相似,但na.omit也会返回一些属性
str(autoN)
#'data.frame': 6 obs. of 2 variables:
# $ v1: int 1 2 2 2 3 3
# $ v2: int 3 3 3 1 4 2
str(auto1)
#'data.frame': 6 obs. of 2 variables:
# $ v1: int 1 2 2 2 3 3
# $ v2: int 3 3 3 1 4 2
# - attr(*, "na.action")=Class 'omit' Named int [1:4] 2 7 8 10
# .. ..- attr(*, "names")= chr [1:4] "2" "7" "8" "10"
Run Code Online (Sandbox Code Playgroud)
并且与complete.cases基于下面显示的基准相比会更慢.
set.seed(238)
df1 <- data.frame(v1 = sample(c(NA, 1:9), 1e7, replace=TRUE),
v2 = sample(c(NA, 1:50), 1e7, replace=TRUE))
system.time(na.omit(df1))
# user system elapsed
# 2.50 0.19 2.69
system.time(df1[complete.cases(df1),])
# user system elapsed
# 0.61 0.09 0.70
Run Code Online (Sandbox Code Playgroud)
set.seed(24)
auto <- data.frame(v1 = sample(c(NA, 1:3), 10, replace=TRUE),
v2 = sample(c(NA, 1:4), 10, replace=TRUE))
Run Code Online (Sandbox Code Playgroud)