0

I am looking for a way to mutate only certain rows of a dataframe based on two conditions. The first condition is always the same (x==1). The second is a recode() of specific values where the first condition is always met.

Here's a very simple version of what I have:

dat <- data.frame(x = c(1, 1, 2, 2),
                  y = c("a", "b", "a", "b"))

dat

#  x y
#1 1 a
#2 1 b
#3 2 a
#4 2 b

Here's what I want:

#  x y z
#1 1 a Apple
#2 1 b Banana
#3 2 a a
#4 2 b b

Nested ifelse statements work, but I have a lot of different y's to define, and I don't want to keep defining x.

dat %>%
  mutate(z = ifelse(x==1 & y=="a", "Apple",
             ifelse(x==1 & y=="b", "Banana", 
                    y)))

The following if() in the pipe does not work, but it's the type of idea I'm going for: when a certain condition is met, do some recoding. I have a lot of recoding to do in my actual use case, so looking for something efficient. I'm trying to do this in the middle of a long pipe that is not shown.

# DOES NOT WORK
dat %>%
  {if(x==1) 
    mutate(., 
           z = recode(y, 
                      "a" = "Apple",
                      "b" = "Banana")
           ) else 
    mutate(., z = y) 
  } 
Eric Green
  • 7,385
  • 11
  • 56
  • 102
  • This seems promising: https://stackoverflow.com/questions/34096162/dplyr-mutate-replace-on-a-subset-of-rows – Eric Green Mar 16 '19 at 04:36
  • the custom `mutate_cond()` function does the trick for me. https://stackoverflow.com/a/34096575/841405 – Eric Green Mar 16 '19 at 04:46
  • This can also be done with `case_when`: `dat %>% mutate(z = case_when(x==1 ~ case_when(y=="a" ~ "Apple", y=="b" ~ "Banana"), TRUE ~ y))`. You'll have to type in the recode values, but you only need to type `x==1` once. – eipi10 Mar 16 '19 at 05:05
  • Or, if you create a lookup table, either in a file or right in your script, you can use `left_join` to add the recoded values. – eipi10 Mar 16 '19 at 05:06
  • 1
    Or, `case_when` plus `recode` (a conditional recode): `dat %>% mutate(z=case_when(x==1 ~ recode(y, a="Apple", b="Banana"), TRUE ~ y))` – eipi10 Mar 16 '19 at 16:16
  • nice use of `case_when()` @epi10 – Eric Green Mar 17 '19 at 17:48

0 Answers0