Reputation: 6132
Been searching for this and even though it should be simple I only found solutions for complete cases or selecting subsets of columns to then omit their NAs. In my case I've got a data frame like this:
vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 NA NA NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA NA NA
3 a NA NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA NA NA
7 NA b NA NA NA NA NA NA NA
It's a very sparse dataframe, and so I want to keep just the rows that have some information, like this:
vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
3 a NA NA NA NA NA NA NA NA
7 NA b NA NA NA NA NA NA NA
Complete cases drops everything and I couldn't find a way to use filter_all
or na.omit()
. Any help would be appreciated.
Thanks!
Upvotes: 4
Views: 149
Reputation: 1234
Using rowSums()
:
require(dplyr)
df %>% filter(rowSums(!is.na(df)) > 0)
Base R
:
df[rowSums(!is.na(df)) > 0,]
Upvotes: 4
Reputation: 21908
You can also go about doing it this way, however it's not quite elegant just practical:
library(dplyr)
DF %>%
filter(DF %>%
rowwise() %>%
summarise(any(!is.na(c_across(everything())))))
vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
3 a <NA> NA NA NA NA NA NA NA
7 <NA> b NA NA NA NA NA NA NA
You can also use any of these two solutions. Special thanks to dear @akrun for suggestions:
library(purrr)
DF %>%
filter(pmap_lgl(DF, ~ any(!is.na(c(...)))))
Or this time we carry out a row-wise operation and directly use filter
:
DF %>%
rowwise() %>%
filter(any(!is.na(c_across(everything()))))
Upvotes: 3
Reputation: 886938
We could either use if_all
library(dplyr)
df1 %>%
filter(!if_all(everything(), is.na))
-output
#vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
#3 a <NA> NA NA NA NA NA NA NA
#7 <NA> b NA NA NA NA NA NA NA
Or with if_any
df1 %>%
filter(if_any(everything(), ~ !is.na(.)))
-output
#vp01ob__0 vp01ob__1 vp01ob__2 vp01ob__3 vp01ob__4 vp01ob__5 vp01ob__6 vp01ob__7 vp01ob__8
#3 a <NA> NA NA NA NA NA NA NA
#7 <NA> b NA NA NA NA NA NA NA
df1 <- structure(list(vp01ob__0 = c(NA, NA, "a", NA, NA, NA, NA), vp01ob__1 = c(NA,
NA, NA, NA, NA, NA, "b"), vp01ob__2 = c(NA, NA, NA, NA, NA, NA,
NA), vp01ob__3 = c(NA, NA, NA, NA, NA, NA, NA), vp01ob__4 = c(NA,
NA, NA, NA, NA, NA, NA), vp01ob__5 = c(NA, NA, NA, NA, NA, NA,
NA), vp01ob__6 = c(NA, NA, NA, NA, NA, NA, NA), vp01ob__7 = c(NA,
NA, NA, NA, NA, NA, NA), vp01ob__8 = c(NA, NA, NA, NA, NA, NA,
NA)), class = "data.frame", row.names = c("1", "2", "3", "4",
"5", "6", "7"))
Upvotes: 3