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>