2
votes

Using dplyr, I am trying to conditionally update values in a column using ifelse and mutate. I am trying to say that, in a data frame, if any variable (column) in a row is equal to 7, then variable c should become 100, otherwise c remains the same.

df <- data.frame(a = c(1,2,3),
                 b = c(1,7,3),
                 c = c(5,2,9))

df <- df %>%  mutate(c = ifelse(any(vars(everything()) == 7), 100, c))

This gives me the error:

Error in mutate_impl(.data, dots) : 
  Evaluation error: (list) object cannot be coerced to type 'double'.

The output I'd like is:

  a b   c
1 1 1   5
2 2 7 100
3 3 3   9

Note: this is an abstract example of a larger data set with more rows and columns.

EDIT: This code gets me a bit closer, but it does not apply the ifelse statement by each row. Instead, it is changing all values to 100 in column c if 7 is present anywhere in the data frame.

df <- df %>%  mutate(c = ifelse(any(select(., everything()) == 7), 100, c))

  a b   c
1 1 1 100
2 2 7 100
3 3 3 100

Perhaps this is not possible to do using dplyr?

2

2 Answers

4
votes

I think this should work. We can check if values in df equal to 7. After that, use rowSums to see if any rows larger than 0, which means there is at least one value is 7.

df <- df %>% mutate(c = ifelse(rowSums(df == 7) > 0, 100, c))

Or we can use apply

df <- df %>% mutate(c = ifelse(apply(df == 7, 1, any), 100, c))

A base R equivalent is like this.

df$c[apply(df == 7, 1, any)] <- 100
1
votes

You could try with purrr::map_dbl

library(purrr)
df$c <- map_dbl(1:nrow(df), ~ifelse(any(df[.x,]==7), 100, df[.x,]$c))

Output

  a b   c
1 1 1   5
2 2 7 100
3 3 3   9

In a dplyr::mutate statement this would be

library(purrr)
library(dplyr)
df %>%
   mutate(c = map_dbl(1:nrow(df), ~ifelse(any(df[.x,]==7), 100, df[.x,]$c)))