larsonsm
larsonsm

Reputation: 45

In dplyr, mutate a logical column where any of a set of other logical columns are true

I have a data frame that looks like this:

typ1  typ2  typ3
   T     T     F
   F     F     F
   T     F     F

and I want mutate a 4th logical column determining if any of the other three are TRUE, so {T, F, T}.

mutate(isAnyType = any(typ1, typ2, typ3)) seems to be using the whole columns, when I would like to use the information per row. Any insight is appreciated.

Upvotes: 2

Views: 1155

Answers (3)

Conner Sexton
Conner Sexton

Reputation: 331

If you take advantage of the boolean values being stored as T = 1, F = 0, I believe you could use the rowSums() function to evaluate instances of T/F row-wise. Is this what you're looking for?

input:

df <- data.frame(typ1 = c(T, F, T),
                 typ2 = c(T,F, F),
                 typ3 = c(F, F, F))
library(dplyr)
df %>% 
  mutate(typ4 = ifelse(rowSums(df) ==0, F, T))

output:

   typ1  typ2  typ3  typ4
1  TRUE  TRUE FALSE  TRUE
2 FALSE FALSE FALSE FALSE
3  TRUE FALSE FALSE  TRUE

Upvotes: 0

larsonsm
larsonsm

Reputation: 45

Looks like the answer can be found here: Using any() vs | in dplyr::mutate

Rather than any(), which utilizes the whole dataframe, I can just use the OR operator, so that mutate(isAnyType = typ1 |typ2 |typ3)) would work

Upvotes: 0

akrun
akrun

Reputation: 886948

We can use reduce with | to check if there are any TRUE elements in each row

library(dplyr)
library(purrr)
df1 %>%
   mutate(isAnyType = reduce(., `|`))

Or using rowSums in base R

df1$isAnyType <- rowSums(df1) > 0

Or another option is pmap

df1 %>%
   mutate(isAnyType = pmap_lgl(., ~ any(c(...)))

data

df1 <- structure(list(typ1 = c(TRUE, FALSE, TRUE), typ2 = c(TRUE, FALSE, 
FALSE), typ3 = c(FALSE, FALSE, FALSE)), class = "data.frame", 
row.names = c(NA, 
-3L))

Upvotes: 2

Related Questions