R select column based on row value

Viewed 173

I have found multiple answers where one can select a row based on a value of a column, but I need the reverse. Consider this example:

library(dplyr)
df <- readr::read_table2("Location       Site     Species    Date     Time
TRUE         TRUE        TRUE       TRUE    TRUE
TRUE         TRUE        TRUE       TRUE    TRUE
TRUE         TRUE        FALSE       TRUE    FALSE
TRUE         TRUE        TRUE     TRUE    TRUE
TRUE       TRUE        TRUE     TRUE    TRUE
TRUE       TRUE        TRUE     TRUE    TRUE")

How can I get the columns or column names which have the values FALSE, considering I know it is in the third row.

I tried something like this: df[3,df[3,]==FALSE], but this gives me an error.

5 Answers

You can use the following solution:

library(dplyr)

df %>%
  select(where(~ any(. == FALSE))) %>%
  names()

[1] "Species" "Time"  

Maybe something along the lines like this:

df <- readr::read_table2("Location       Site     Species    Date     Time
                          TRUE         TRUE        TRUE       TRUE    TRUE
                          TRUE         TRUE        TRUE       TRUE    TRUE
                          TRUE         TRUE        FALSE       TRUE    FALSE
                          TRUE         TRUE        TRUE     TRUE    TRUE
                          TRUE       TRUE        TRUE     TRUE    TRUE
                          TRUE       TRUE        TRUE     TRUE    TRUE")
which(df == FALSE, arr.ind = TRUE)[,2] #gives you the col numbers

The argument arr.ind, if True, gives you the array indices from which you can extract the column numbers

Here are few options :

Base R -

#1. Using colSums
names(df)[colSums(!df) > 0]
#Also
#names(df)[colSums(df) != nrow(df)]

#2. Using `Filter`
names(Filter(function(x) any(!x), df))
#Also
#names(Filter(function(x) !all(x), df))

#3. Using `sapply`
names(df)[!sapply(df, all)]

With purrr :

#1. Using `keep`
names(purrr::keep(df, ~any(!.x)))

#2. Using `discard`
names(purrr::discard(df, all))

Another option:

apply(df, 2, function(df) which (df %in% FALSE))

Output:

$Location
integer(0)

$Site
integer(0)

$Species
[1] 3

$Date
integer(0)

$Time
[1] 3

The number indicates the number of row.

We can use select_if

library(dplyr)
df %>% 
  select_if(~ any(!.)) %>%
  names
Related