#r #loops
#r #циклы
Вопрос:
У меня есть фрейм данных с одним столбцом. Я пытаюсь создать файл сопоставления и хочу, чтобы команда grep показывала, какое совпадение было извлечено.
df<- data.frame("Restaurant" = c("Dominos Pizza", "Papa Johns Pizza", "Dairy Queen Ice Cream", "Dennys Breakfast")
Я пробовал:
tags<- c("Pizza", "Breakfast", "Cream")
for (i in length(tags)) {
df$i <- df[grep(i, df$Restaurant),]
}
Я хочу, чтобы мой желаемый результат был:
Ресторан Dominos Pizza Pappa Johns Пицца Мороженое Dairy Queen
Затем я могу расплавить df для создания сопоставления
Ответ №1:
Попробуйте это. Вы можете использовать ifelse()
и grepl()
для проверки условий, а затем использовать те же tags
значения для создания новых переменных. Здесь код:
#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)
}
Вывод:
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>
Ответ №2:
Вот мысль, цикл не требуется:
# 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
Отсюда не так уж сложно заменить логические данные реальными строками:
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>
Альтернативы, которые делают почти то же самое. Начиная с 1 столбца 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>
или
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>
Комментарии:
1. Большое спасибо, первый набор кода работает отлично, но второй возвращает эту ошибку Ошибка meassage в !lgl: недопустимый тип аргумента
2. Не уверен, что сказать … это работает для меня, когда столбцы имеют класс
logical
.str(df)
Предполагает, чтоPizza
(etc) все логические? Вы должны увидетьPizza : logi ...
.3. Да, это так, код выполняется без! перед lgl, но, очевидно, не правильный вывод
4. хорошо, есть ли другие столбцы, которыми вы не поделились?
df[,-1]
означает каждый столбец, кроме первого ($Restaurant
), возможно, вы используете слишком много столбцов? Попробуйтеdf[,2:4] <- lapply(df[,2:4], ...)
5. Я могу воспроизвести эту ошибку только тогда, когда логические столбцы больше не являются логическими. Например, если вы запустите мой код выше (с моими данными… работайте со мной здесь) с
df <- data.frame(...)
концаdf[,-1] <- lapply(...)
, затем повторите эту последнююlapply
команду, я вижу ошибку. Если вы случайно запустили его дважды, эта ошибка верна, не делайте этого. Если вы используете слишком много столбцов, укажите более конкретно (в своем коде), какие столбцы, а не только-1
. Какие бы изменения вы ни вносили в индексы столбцов в LHS, делайте это и в RHS.