Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update cell values with the column name using mutate_at

Tags:

r

dplyr

I am processing survey data. Some of the questions ask participants to check all of the options that apply to them. In the dataframe I currently have, there is a column for each of the possible responses, with a value of 1 recorded if the participant selected that option. For example, for the question "Which of the following emotions have you experienced at work?", with the options "Boredom", "Stress", "Contentment", my dataframe would look like this:

df <- data.frame(
  id = seq(1,3,1),
  boredom = c(NA, 1, NA),
  stress = c(1, 1, 1),
  contentment = c(NA, NA, NA)
)

I want to update any cell values equal to 1 with the name of the column, so that I have a dataframe that looks like this:

df2 <- data.frame(
  id = seq(1,3,1),
  boredom = c(NA, 'boredom', NA),
  stress = rep('stress', 3), 
  contentment = rep(NA, 3)
)

I can then use dplyr::unite to create a column that stores all the emotions that participants report experiencing in one column.

My intuitive approach is to use mutate_at and ifelse(), but I don't know how to reference the name of the column in the call to ifelse(). For example, I want to write something like this:

df_updated <- df %>% 
  mutate_at(vars(boredom:stress), funs(ifelse(. == 1, 'relevant column name', .)))

I am hoping someone can tell me how to access the column name in the ifelse() call. Or, if I'm barking up the wrong tree, guidance on another approach is also very welcome.

like image 781
userLL Avatar asked Mar 22 '26 02:03

userLL


2 Answers

Try this:

df %>% mutate_at(vars(boredom:stress), funs(ifelse(. == 1, deparse(substitute(.)), .)))
like image 94
parkerchad81 Avatar answered Mar 23 '26 19:03

parkerchad81


Another option is to convert data from wide to long, then change values as required before reshaping back to wide again.

df %>%
    gather(key, val, -id) %>%
    mutate(val = ifelse(val == 1, key, val)) %>%
    spread(key, val) %>%
    select(names(df))
#  id boredom stress contentment
#1  1    <NA> stress        <NA>
#2  2 boredom stress        <NA>
#3  3    <NA> stress        <NA>
like image 21
Maurits Evers Avatar answered Mar 23 '26 18:03

Maurits Evers