Creating a grep loop to find character values and then map matches in new Column

Viewed 72

I have a data frame with one columns. I am trying to create a mapping file and want the grep command to show which match was pulled.

df<- data.frame("Restaurant" = c("Dominos Pizza", "Papa Johns Pizza", "Dairy Queen Ice Cream", "Dennys Breakfast")

I have tried:

tags<- c("Pizza", "Breakfast", "Cream")

for (i in length(tags)) {
df$i <- df[grep(i, df$Restaurant),]
  
}

I want my desired output to be:

Restaurant Dominos Pizza Pappa Johns Pizza Dairy Queen Ice Cream

enter image description here

I then can melt the df to create the mapping

2 Answers

Try this. You can use ifelse() and grepl() to test the conditions and then use the same tags values to create the new variables. Here the code:

#Data
df<- data.frame("Restaurant" = c("Dominos Pizza", "Papa Johns Pizza", "Dairy Queen Ice Cream", "Dennys Breakfast"),stringsAsFactors = F)
tags<- c("Pizza", "Breakfast", "Cream")
#Loop
for(i in 1:length(tags))
{
  df[[tags[i]]] <- ifelse(grepl(tags[i],df$Restaurant),df$Restaurant,NA)
}

Output:

df
             Restaurant            Pizza        Breakfast                 Cream
1         Dominos Pizza    Dominos Pizza             <NA>                  <NA>
2      Papa Johns Pizza Papa Johns Pizza             <NA>                  <NA>
3 Dairy Queen Ice Cream             <NA>             <NA> Dairy Queen Ice Cream
4      Dennys Breakfast             <NA> Dennys Breakfast                  <NA>

Here's a thought, no loop required:

# add the closing paren
df<- data.frame("Restaurant" = c("Dominos Pizza", "Papa Johns Pizza", "Dairy Queen Ice Cream", "Dennys Breakfast"))
tags<- c("Pizza", "Breakfast", "Cream")

df <- cbind(df, sapply(tags, grepl, df$Restaurant))
df
#              Restaurant Pizza Breakfast Cream
# 1         Dominos Pizza  TRUE     FALSE FALSE
# 2      Papa Johns Pizza  TRUE     FALSE FALSE
# 3 Dairy Queen Ice Cream FALSE     FALSE  TRUE
# 4      Dennys Breakfast FALSE      TRUE FALSE

From here, it's not too hard to replace the logicals with actual strings:

df[,-1] <- lapply(df[,-1], function(lgl) replace(df$Restaurant, !lgl, values = NA_character_))
df
#              Restaurant            Pizza        Breakfast                 Cream
# 1         Dominos Pizza    Dominos Pizza             <NA>                  <NA>
# 2      Papa Johns Pizza Papa Johns Pizza             <NA>                  <NA>
# 3 Dairy Queen Ice Cream             <NA>             <NA> Dairy Queen Ice Cream
# 4      Dennys Breakfast             <NA> Dennys Breakfast                  <NA>

Alternatives that do much the same thing. Starting with the 1-column df:

cbind(df, lapply(setNames(nm = tags), function(tg) replace(df$Restaurant, !grepl(tg, df$Restaurant), NA_character_)))
#              Restaurant            Pizza        Breakfast                 Cream
# 1         Dominos Pizza    Dominos Pizza             <NA>                  <NA>
# 2      Papa Johns Pizza Papa Johns Pizza             <NA>                  <NA>
# 3 Dairy Queen Ice Cream             <NA>             <NA> Dairy Queen Ice Cream
# 4      Dennys Breakfast             <NA> Dennys Breakfast                  <NA>

or

cbind(df, lapply(setNames(nm = tags), function(tg) ifelse(grepl(tg, df$Restaurant), df$Restaurant, NA_character_)))
#              Restaurant            Pizza        Breakfast                 Cream
# 1         Dominos Pizza    Dominos Pizza             <NA>                  <NA>
# 2      Papa Johns Pizza Papa Johns Pizza             <NA>                  <NA>
# 3 Dairy Queen Ice Cream             <NA>             <NA> Dairy Queen Ice Cream
# 4      Dennys Breakfast             <NA> Dennys Breakfast                  <NA>

Related