1
votes

I am trying to use dplyr to mutate (or mutate_if?) column2 of a dataframe based on the contents of column1.

ID    TEST    PREF
11    true    blue
23    false   red
4     false   yellow

if test == "false", I would like to mutate PREF = "orange". Otherwise, do not change PREF.

ID    TEST    PREF
11    true    blue
23    false   orange
4     false   orange

I thought an ifelse statement might work but can't understand how to make else do nothing. It seems to return the column number instead of the contents at that row.

df <- data.frame(ID = c("11", "23", "4"),
                 TEST = factor(c("true", "false", "false")),
                 PREF = factor(c("blue", "red", "yellow")))

df <- df %>%
  mutate(PREF = ifelse(TEST == "false", "orange", PREF))

I feel like mutate_if should be appropriate but I don't think I understand its function very well and I can't find any examples similar to what I need. Something like:

df <- df %>%
  mutate_if(TEST == "true", PREF = "orange")

Can anyone please give me some suggestions? Thanks!

Edit:

I have realised that in my ifelse statement it was returning the level of the factor, not the characters I wanted. This works exactly as I was hoping by specifying as.character.

df2 <- df %>%
  mutate(PREF = factor(ifelse(TEST == "false", "white", as.character(PREF))))
1
I think you might just be running into trouble with your capitalization. Your first attempt should work if you change test to TEST and pref to PREF. R is case-sensitive.joshpk
mutate_if is not the right function. The if part of that command looks at properties of the column itself, not any particular row value. You would use mutate_if to change all the numeric columns or characters or impute data in columns with missing values.ifelse is a better choice (note sure what the problem is with the code you posted), see also the "tidy" version called if_else or even the base function replace() might be a better choice.MrFlick
thanks @joshpk - the capitalisation was just me changing the example half way through and not being thorough, you're right - the capitalisation would have been incorrect.dankshan

1 Answers

1
votes

You are onto it! But, you must make sure your character columns are not converted to factors. I don't understand fully why if_else() fails with the factor levels, but at least this adapted code below does what I think you want. stringsAsFactors are as important as ever.

library(dplyr)

df <- data.frame(ID = c("11", "23", "4"),
                 myTEST = c("true", "false", "false"),
                 myPREF = c("blue", "red", "yellow"), stringsAsFactors=F)

new_df <- df %>%
  mutate(myPREF = case_when(myTEST=="false" ~ "orange",
                          TRUE ~ myPREF))

str(new_df)

mutate_if has a tempting name, but the predicate works AFAIK only on columns, and not on rows.