我发现这个函数可以检测任何给定数据帧中每列的缺失值比例:
propmiss <- function(dataframe) lapply(dataframe,function(x) data.frame(nmiss=sum(is.na(x)), n=length(x), propmiss=sum(is.na(x))/length(x)))
我将它分配给这样的变量:
propmissdf <- propmiss(df)
然后我将数据帧循环到我的数据中的NULL变量,如下所示:
for(i in (1:length(df))){
var = names(df)[i]
if((propmissdf[[var]][[3]]) > 0.3) { #the 3 index represents the proportion inside propmissdf
df[var] <- NULL
}
}
这给了我一个错误:
Error in if ((propmissdf[[var]][[3]]) > 0.3) { :argument is of length zero
但不管怎样,它有效。它删除了几个缺少大于0.3的值比例的变量,但如果我再次运行for循环,它会消除更多直到3或4次,直到它摆脱所有这些。为什么会这样?请随时纠正我的问题,或者想出一个更好的方法来删除超过30%的NA的变量。
答案 0 :(得分:2)
您可以使用以下内容:
df <- df[colSums(is.na(df))/nrow(df) < .3]
colSums(is.na(df))
会计算每列中有多少NA
个值。 data.frame
中的行数以获得比例。 < .3
创建可用于对相关列进行子集化的逻辑比较。示例数据和示例:
set.seed(2)
df <- data.frame(matrix(sample(c(NA, 1:4), 20, TRUE), nrow = 4))
df
# X1 X2 X3 X4 X5
# 1 NA 4 2 3 4
# 2 3 4 2 NA 1
# 3 2 NA 2 2 2
# 4 NA 4 1 4 NA
colSums(is.na(df))/nrow(df)
# X1 X2 X3 X4 X5
# 0.50 0.25 0.00 0.25 0.25
df[colSums(is.na(df))/nrow(df) < .3]
# X2 X3 X4 X5
# 1 4 2 3 4
# 2 4 2 NA 1
# 3 NA 2 2 2
# 4 4 1 4 NA
作为参考,这里有一个快速的时间比较:
set.seed(1)
df <- data.frame(matrix(sample(c(NA, 1:4), 4000, TRUE), ncol = 1000))
akfun <- function() {
i1 <-sapply(df, function(x) {
pr <- prop.table(table(factor(is.na(x), levels=c(TRUE, FALSE))))
pr[as.logical(names(pr))]< 0.3
})
df[i1]
}
amfun <- function() df[colSums(is.na(df))/nrow(df) < .3]
identical(amfun(), akfun())
# [1] TRUE
system.time(akfun())
# user system elapsed
# 0.172 0.000 0.173
system.time(amfun())
# user system elapsed
# 0.000 0.000 0.001
答案 1 :(得分:2)
我们可以使用sapply
遍历列,使用count
获取{NA}值的table
,使用`prop.table查找比例并创建逻辑向量。
i1 <-sapply(df, function(x) {
pr <- prop.table(table(factor(is.na(x), levels=c(TRUE, FALSE))))
pr[as.logical(names(pr))]< 0.3
})
此向量可用于对列进行子集化。
df[i1]
如果我们需要删除列
df[!i1] <- list(NULL) #contributed by @Ananda Mahto
df
# X2 X3 X4 X5
#1 4 2 3 4
#2 4 2 NA 1
#3 NA 2 2 2
#4 4 1 4 NA
注意:df
取自@Ananda Mahto的帖子