Перекодировать наблюдение в столбце в зависимости от другого столбца

У меня есть набор данных под названием «опрос» со строками отдельных идентификаторов и столбцами со многими вопросами. Мне нужно перекодировать значение в 1 столбце как NA и переместить наблюдение в другой столбец.

Например:

ID    Food    Vegetable 
aaa   NA       NA 
bbb   NA       lemon
ccc   NA       sprout
ddd   fruit    NA
eee   fruit    NA
fff   NA       watermelon

Я хочу изменить наблюдения lemon и watermelon, принадлежащие ID bbb и fff, чтобы поместить их в столбец Food и переименовать их fruit (респонденты опроса поместили их в неправильный столбец) и оставить NA позади в столбце vegetable.

Выглядеть как:

   ID    Food        Vegetable 
    aaa   NA         NA 
    bbb   fruit      NA
    ccc   NA         sprout
    ddd   fruit      NA
    eee   fruit      NA
    fff   fruit      NA       

Я использовал:

survey<- survey %>%
    mutate(food = if_else(str_detect(Vegetable,"(lemon)|(watermelon)"),"fruit", Food))
 

Который работает для преобразования NA в fruit в столбце food, но не согласуется с NA в столбце vegetable, он также превращает все остальные фрукты в столбце food в NA!

ДАННЫЕ:

    structure(list(ID = c("aaa", "bbb", "ccc", "ddd", "eee", "fff"
), Food = c(NA, NA, NA, "fruit", "fruit", NA), Vegetable = c(NA, 
"lemon", "sprout", NA, NA, "watermelon")), class = "data.frame", row.names = c(NA, 
-6L))

P.S.: Это продолжение предыдущего вопроса, который я задал, на который был дан ответ. Это не совсем тот же вопрос, что и раньше, поэтому я задал новый.

версия dplyr (1.0.2)

После шага вы можете сделать mutate(Vegetable = NA_character_)

akrun 20.12.2020 22:23
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
77
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Один из вариантов — обновить Food и Vegetable в зависимости от того, являются ли значения Vegetable%in% заданным списком, not_vegetables:

not_vegetables <- c("grape", "tomato")

df %>%
  mutate(Food = if_else(Vegetable %in% not_vegetables, "fruit", Food),
         Vegetable = if_else(Vegetable %in% not_vegetables, NA_character_, Vegetable))

Другой способ - replace, across оба столбца и сделать if_else внутри:

df %>%
  mutate(across(
    c(Food, Vegetable), 
    ~replace(., 
             Vegetable %in% not_vegetables, 
             if_else(cur_column() == "Food", 'fruit', NA_character_))
    ))

К сожалению, ни один из них, похоже, не сработал? Первое решение запустилось, но никаких изменений в данных. второе решение дало ошибку: Error: Problem with `mutate()` input `..1`. x Formula shorthand must be wrapped in `where()`. # Bad data %>% select(~...) # Good data %>% select(where(~...)) ℹ Input `..1` is `across(...)`. Backtrace: >

Gabriella 21.12.2020 12:58

Я протестировал оба локально перед публикацией, похоже на проблему с версией и / или что-то о том, как настроены ваши реальные данные. Какая у вас версия dplyr? across был представлен в апреле. Можете ли вы отредактировать свой пост, чтобы включить dput ваших данных или вашего игрушечного df? Так будет легче узнать, что происходит.

andrew_reece 21.12.2020 15:29

Как ни странно, когда я делаю это в новом файле R, он работает... возможно ли, что %in% замаскирован другим пакетом?

Gabriella 21.12.2020 19:21

Рад, что это сработало. Перемаскировка, может быть? Вы можете посмотреть на conflicts(detail=TRUE), чтобы увидеть, какие функции конфликтуют в вашей среде. Обратите внимание, что %in% — это базовая функция R, я не думаю, что что-либо в tidyverse перезаписывает ее.

andrew_reece 21.12.2020 19:32

Используя базу R, вы могли бы попробовать это:

#Conditional
values <- c('grape','tomato')
df$Food <- ifelse(df$Vegetable %in% values,'fruit',df$Food)
df$Vegetable <- ifelse(df$Vegetable %in% values,NA,df$Vegetable)

Выход:

df
   ID  Food Vegetable
1 aaa fruit      <NA>
2 bbb fruit      <NA>
3 ccc fruit      <NA>
4 ddd fruit      <NA>

Данные

df <- structure(list(ID = c("aaa", "bbb", "ccc", "ddd"), Food = c(NA, 
NA, "fruit", "fruit"), Vegetable = c("grape", "tomato", NA, NA
)), class = "data.frame", row.names = c(NA, -4L))

Другие вопросы по теме