从data.frame中删除列,其中NA大于列长度的15%

时间:2012-08-06 00:24:53

标签: r dataframe

我有10个不同列的data.frame(每列的长度相同)。我想删除任何列'NA'大于列长度的列。

我是否首先需要创建一个函数来计算每列NA的百分比,然后在我应用函数的位置再创建一个data.frame?最好的方法是什么?

2 个答案:

答案 0 :(得分:8)

首先,分享一些样本数据总是好的。它不需要是你的实际数据 - 组成的东西很好。

set.seed(1)
x <- rnorm(1000)
x[sample(1000, 150)] <- NA
mydf <- data.frame(matrix(x, ncol = 10))

其次,您可以使用内置函数来获取所需内容。在此处,is.na(mydf)进行逻辑检查并返回data.frame TRUEFALSE。由于TRUEFALSE等同于10,我们可以使用colMeans来获取TRUE的数量的平均值(是NA)值。反过来,可以根据您的规定检查,在这种情况下,哪些列的NA值超过15%?

colMeans(is.na(mydf)) > .15
#    X1    X2    X3    X4    X5    X6    X7    X8    X9   X10 
#  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE  TRUE FALSE

我们可以看到,我们应该放弃X1,X2,X6,X8和X9。再次,利用逻辑向量,这是如何:

> final <- mydf[, colMeans(is.na(mydf)) <= .15]
> dim(final)
[1] 100   5
> names(final)
[1] "X3"  "X4"  "X5"  "X7"  "X10"

答案 1 :(得分:0)

你可以使用data.table这样做

将数据加载到data.table中。叫它DT。比如cols 2到4是数字。

Theta = 0.15
Drop <- DT[, lapply(.SD, function (x) {sum(is.na(x))/length(x) > Theta} ), .SDcols = 2:4]
Cols.2.Drop <- names(Drop)[which(Drop==TRUE)]
DT[, (Cols.2.Drop) := NULL]

在此测试数据:

Obs Var1    Var2    Var3
A0001   21  21  21
A0002   21  78  321
A0003   32  98  87
A0004   21  12  54
A0005   21  13  45
A0006   21  87  45
B0007   84  NA  45
B0008   21  NA  98
B0009   2   NA  45
B0010   12  NA  45