Apologies if this has been asked elsewhere and I wasn't able to find it. I have a data frame with a character vector, say
library(tidyverse)
mydf <- data.frame(value = c('c','e','a','d'))
and a list, the names imperfectly correspond to the character vector value
in mydf
mylist <- list ('a' = '1',
'b' = '2',
'c' = '3',
'd' = '4')
How can I define a new variable in mydf
that takes on the elements of an item in the list if value
equals the name of a given list item?
In other words, the desired output is
mydf2 <- data.frame(value = c('c','e','a','d'),
value2 = c('3', 'e', '1', '4'))
I assume that this can be done with case_when
and perhaps bang-bang notation but I can't quite square it.
CodePudding user response:
unlist
the list
and use the named vector to match
and replace the values in 'value' column and then with coalesce
replace the non-matching i.e. NA
to original column values
library(dplyr)
mydf3 <- mydf %>%
mutate(value2 = coalesce(unlist(mylist)[value], value))
-output
mydf3
value value2
1 c 3
2 e e
3 a 1
4 d 4
Or another option is a join after converting the named list
to a two column data.frame (stack
) and then either use coalesce
or case_when/ifelse
mydf %>%
left_join(stack(mylist), by = c("value"= "ind")) %>%
transmute(value, value2 = case_when(is.na(values) ~ value, TRUE ~ values))
value value2
1 c 3
2 e e
3 a 1
4 d 4