Вложенный ifelse, возвращает исходное значение для ‘else’?

#r #dplyr

#r #dplyr

Вопрос:

У меня есть вложенный оператор ifelse, подобный этому:

 combined_data <- original %>%
  mutate(new_column = as.character(ifelse(grepl("Apple", list), "Granny Smith Apple",
                                   ifelse(grepl("Banna", list), "Organic Banana",
                                   ifelse(grepl("Spinach", list), "Baby Spinach",
                                   ifelse(grepl("Watermelon", list), "Seedless Watermelon", list))))))
 

Столбец «список» имеет, скажем, ~ 10 значений. Если оно не соответствует ни одному из этих значений, я хочу, чтобы значение «new_column» возвращало все, что было в списке. Например, если столбец list имеет:

 Apple
Spinach
Watermelon
Orange
Kale
 

Если я выполняю вышеуказанное и использую list , то я просто получаю коэффициент элементов в списке, и мой вывод выглядит так:

 Granny Smith Apple
Baby Spinach
Seedless Watermelon
5
5
 

Но new_coulumn должен вернуть:

 Granny Smith Apple
Baby Spinach
Seedless watermelon
Orange
Kale
 

Как я могу это получить?

Комментарии:

1. Почему бы вам просто не добавить неизмененные элементы в свой список дескрипторов, чтобы устранить необходимость в более сложной логике кодирования?

Ответ №1:

Поскольку вы используете dplyr , я бы настоятельно рекомендовал case_when в качестве более простой альтернативы вложенному ifelse() . ( case_when также строже относится к типам, поэтому он выдал бы ошибку о несоответствии фактора / символа).

case_when Версия вашего кода такая:

 original %>%
  mutate(new_column = case_when(
    grepl("Apple", list) ~ "Granny Smith Apple",
    grepl("Banna", list) ~ "Organic Banana",
    grepl("Spinach", list) ~ "Baby Spinach",
    grepl("Watermelon", list) ~ "Seedless Watermelon",
    TRUE ~ as.character(list)
  ))
 

Я бы также поставил под сомнение, нужно вам это или нет grepl … Если вам нужно искать шаблоны внутри строк, например, вы хотите изменить "string containing Apple" на "Granny Smith Apple" , тогда да, вам нужно grepl . Однако, если вы выполняете точное сопоставление целых строк, вам не нужно grepl , вы можете просто использовать == . Использование == вместо grepl будет более эффективным и менее подверженным ошибкам (особенно, если в ваших строках могут быть символы, которые могут быть специальными символами в регулярных выражениях).

 original %>%
  mutate(new_column = case_when(
    list == "Apple" ~ "Granny Smith Apple",
    list == "Banna" ~ "Organic Banana",
    list == "Spinach" ~ "Baby Spinach",
    list == "Watermelon" ~ "Seedless Watermelon",
    TRUE ~ as.character(list)
  ))
 

Ответ №2:

Я исправил это, он возвращал фактор, а не символ.

Использовал это как мое решение:

 combined_data <- original %>%
  mutate(new_column = as.character(ifelse(grepl("Apple", list), "Granny Smith Apple",
                                   ifelse(grepl("Banna", list), "Organic Banana",
                                   ifelse(grepl("Spinach", list), "Baby Spinach",
                                   ifelse(grepl("Watermelon", list), "Seedless Watermelon", as.character(list)))))))
 

Ответ №3:

Мы можем использовать str_detect , который также векторизован

 library(dplyr)
library(stringr)
original %>%
    mutate(new_column = ~ case_when(!str_detect(list, newcol)~ newcol, TRUE ~ list))