Mark
Mark

Reputation: 1769

Check if there exists, in a dataframe, a row with all `NA`

Check if there exists, in a dataframe, a row with all NA. For example, the answer for this dataframe is yes:

my.df <- data.frame(a=c(1, NA, 3), b=c(5, NA, NA))

but it is not true for the following

my.df2 <- data.frame(a=c(1, 2, 3), b=c(5, NA, NA))

Upvotes: 1

Views: 90

Answers (5)

ThomasIsCoding
ThomasIsCoding

Reputation: 102309

Another base R option is using any + Reduce + asplit

any(Reduce("&", asplit(is.na(df), 2)))

where df is the input data.frame

Upvotes: 0

Chris Ruehlemann
Chris Ruehlemann

Reputation: 21432

You can use rowSums and is.na:

my.df[which(rowSums(is.na(my.df[]))==2),]
   a  b
2 NA NA

If you have dataframes with variable numbers of columns, you can use length:

my.df[which(rowSums(is.na(my.df[])) == length(my.df)),]

Upvotes: 1

akrun
akrun

Reputation: 887531

An option is to create a function which converts the data to logical matrix (is.na), get the rowwise sum of the elements that are NA, check if it is equal to the number of columns and wrap if there are any rows having that meets

f1 <- function(dat) any(rowSums(is.na(dat)) == ncol(dat))

f1(my.df)
#[1] TRUE
f1(my.df2)
#[1] FALSE

NOTE: rowSums is vectorized and should be very fast


Or another option with tidyverse

library(dplyr)
f2 <- function(dat) {
     dat %>%
         filter(across(everything(), is.na)) %>%
         nrow %>% 
         magrittr::is_greater_than(0)
  }

f2(my.df)
#[1] TRUE
f2(my.df2)
#[1] FALSE

Upvotes: 1

SteveM
SteveM

Reputation: 2301

allNA <- apply(my.df, 1, function(x) all(is.na(x)))
allNA
[1] FALSE  TRUE FALSE
sum(allNA) # determine if there is at least 1 allNA row
[1] 1

Upvotes: 1

Duck
Duck

Reputation: 39613

Another option can be:

#Code
myfun <- function(x)
{
  y <-apply(x,1,function(x) length(which(is.na(x))))
  any(y==ncol(x))
}
#Apply
myfun(my.df)
myfun(my.df2)

Output:

myfun(my.df)
[1] TRUE
myfun(my.df2)
[1] FALSE

Upvotes: 1

Related Questions