6

I am trying to filter out rows with NA values across multiple columns. A row should only be dropped if all columns of interest are NA.

The scenario is the same as in this question (but I don't have enough reputation to make a comment): filtering data frame based on NA on multiple columns

One of the solutions is to use:

library(dplyr)
df_non_na <- df %>% filter_at(vars(type,company),all_vars(!is.na(.)))

Since "filter_at" is being depreciated in dplyr, how can I use "filter" and "across" to achieve a similar outcome?

etrowbridge
  • 355
  • 3
  • 8
  • 1
    Does this answer your question? [dplyr filter with condition on multiple columns](https://stackoverflow.com/questions/43938863/dplyr-filter-with-condition-on-multiple-columns) – camille Feb 28 '21 at 19:23

1 Answers1

10

We can use across to loop over the columns 'type', 'company' and return the rows that doesn't have any NA in the specified columns

library(dplyr)
df %>%
     filter(across(c(type, company), ~ !is.na(.)))
#     id  type company
#1  3 North    Alex
#2 NA North     BDA

With filter, there are two options that are similar to all_vars/any_vars used with filter_at/filter_all

df %>%
  filter(if_any(c(company, type), ~ !is.na(.)))
#  id  type company
#1  2  <NA>     ADM
#2  3 North    Alex
#3  4 South    <NA>
#4 NA North     BDA
#5  6  <NA>      CA

Or using if_all

    df %>%
      filter(!if_all(c(company, type), is.na))
   id  type company
1  2  <NA>     ADM
2  3 North    Alex
3  4 South    <NA>
4 NA North     BDA
5  6  <NA>      CA

data

df <- structure(list(id = c(1L, 2L, 3L, 4L, NA, 6L), type = c(NA, NA, 
"North", "South", "North", NA), company = c(NA, "ADM", "Alex", 
NA, "BDA", "CA")), class = "data.frame", row.names = c(NA, -6L
))
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Is there a way to modify this so that only rows with multiple "NA" values are removed? For example, so that only the first row in df (where both "type" and "company" are NA) would be removed. – etrowbridge Feb 28 '21 at 19:20
  • @etrowbridge please check the updated solution – akrun Feb 28 '21 at 19:28
  • 1
    I tried to use `filter(if_all(c(variables), ~ !is.na(.)))` but it did not work as intended. I had to move the exclamation point before `if_all()` – Michael Matta Jan 07 '23 at 00:22