2016-03-27 23 views
0

识别行我有这样一个数据帧(DF)用的缺失值:其中所有元件被缺失值-R

DF:

head1 head2 head3 
----- ----- ----- 
34  32  6 
NA  NA  NA 
45  NA  11 
54  15  98 
45  56  NA 
3  1  78 
NA  5  NA 

我想返回这样的列(头像4)

head1 head2 head3 head4 
----- ----- ----- ----- 
34  32  6  0 
NA  NA  NA  1 
45  NA  11  0 
54  15  98  0 
45  56  NA  0 
3  1  78  0 
NA  5  NA  0 

即,如果行的所有元素都是一个缺失值(NA),那么相关行将返回1,否则返回0.我怎样才能使用R?我会很乐意提供任何帮助。非常感谢。

回答

4

你可以尝试

df$head4 <- +(rowSums(is.na(df))==ncol(df)) 
# head1 head2 head3 head4 
#1 34 32  6  0 
#2 NA NA NA  1 
#3 45 NA 11  0 
#4 54 15 98  0 
#5 45 56 NA  0 
#6  3  1 78  0 
#7 NA  5 NA  0 

在这种情况下rowSums()计数每一行的NA值。如果该行中的所有条目均为NA,则该总和等于数据帧的总列数,与==ncol(df)的比较返回TRUE。否则结果是FALSE。通过在前面添加+符号,可以将布尔向量强制为数字值(0/1),在这种情况下,这是as.numeric()的简写符号。

希望这会有所帮助。


由于已经由@RichardTelford关于不同的答案的速度评论,我试图验证是否根据该其他答案的人会快两倍,这一次是真的他的要求。

m <- matrix(runif(1e6),ncol=4) 
nas <- sample(1e6,0.3*1.e6) 
m[nas] <- NA 
df <- as.data.frame(m) 
library(microbenchmark) 
frowsums <- function(x) {+(rowSums(is.na(x))==ncol(x))} 
flapply <- function(x) {Reduce(`&`, lapply(x, is.na)) + 0L} 
frowmeans <- function(x) {1*(rowMeans(is.na(x)) == 1)} 
res <- microbenchmark(
    frowsums(df), 
    flapply(df), 
    frowmeans(df), times=1000L) 
res 
Unit: milliseconds 

      expr  min  lq  mean median  uq  max neval cld 
    frowsums(df) 15.75257 16.63475 20.23377 17.14405 17.82396 80.63485 1000 b 
    flapply(df) 15.16721 15.23180 18.19778 16.13413 16.60948 88.92303 1000 a 
frowmeans(df) 16.61643 17.56909 20.69433 18.03498 18.83867 81.54057 1000 b 

由于结果显示@ RichardTelford的说法不正确。这三种解决方案之间的速度几乎没有任何区别,这意味着从程序员的角度来看,最简单的版本和更易于理解的版本应该更可取。

3

您可以找到is.na NAS(),然后测试,如果行中的所有元素都是1)rowMeans的帮助(

df$head4 <- 1*(rowMeans(is.na(df)) == 1) 

乘以1强制转换的逻辑载体的数字矢量(你也许并不需要做到这一点)

4

我建议Reduce & lapply组合,避免了矩阵转换和一次复制整个对象到内存中。

Reduce(`&`, lapply(df, is.na)) + 0L 
# [1] 0 1 0 0 0 0 0 
+0

microbenckmark显示该解决方案的速度是其他两个速度的两倍。 rowMeans解决方案比rowSums解决方案快大约20%。 –