I have a list of lists, like this example. For reference, my data has 300 lists each with around 90 components each, but of unequal length which is why it must stay in a list (I believe)
a <- list("FRUITS" = c("apples","bananas","pears"),
"VEGGIES" = c("lettuce","pepper","carrot"),
"BREADS" = c("bagel","muffin","sandwhich"))
and a dataframe that looks like this but has thousands of rows
b <- data.frame("Sample" = c("BB","TT","LT"),
"Food" = c("SandWich","Tomato","BANANA"),
"Volume" = c(124,1356,1343))
My goal is for my dataframe to mutate a new column that contains the list name that each Food item resides in. This is where Lookup/Finding strings within a list of lists and returning the list's name comes from.
data.frame("Sample" = c("BB","TT","LT"),
"Food" = c("SandWich","Tomato","BANANA"),
"Volume" = c(124,1356,1343),
"Match" = c("BREADS","VEGGIES","FRUITS")
How can I do this? I have tried using other techniques on stack that around similar to Excel's VLOOKUP but no other threads are returning the lists' name from what I can tell.
Thanks for any help or feedback.
Edit: Case sensitivity
CodePudding user response:
In base R
transform(merge(b, stack(a), by.x = c("Food"), by.y = "values"),
Food = ind, ind = NULL)
Or in tidyverse
library(tibble)
library(dplyr)
library(tidyr)
enframe(a, value = "Food") %>%
unnest(Food) %>%
right_join(b, by = "Food") %>%
mutate(Food = coalesce(name, Food), name = NULL)
If we need to change the case
library(purrr)
map(a, toupper) %>%
enframe(value = "Food") %>%
unnest(Food) %>%
right_join(b %>%
mutate(Food = toupper(Food)), by = "Food") %>%
mutate(Food = coalesce(name, Food), name = NULL)