IFELSE в R возвращает неправильные значения - PullRequest
2 голосов
/ 28 февраля 2020

У меня есть фрейм данных с категориальными значениями, которые были введены вручную, и есть несколько ошибок. Кто-то очистил плохие данные, и я загрузил их в R и объединил их с остальными данными. Пока все хорошо.

В качестве примера, скажем, это данные, которые у меня есть с исходными данными (смесь хороших и плохих данных) в столбце «Значение» и исправлениями плохих данных в столбце «Значение_чисти». Очевидно, это небольшой пример, но мой фактический фрейм данных содержит десятки поправок разных значений и несколько тысяч строк.

test <- data.frame(ID = c(1, 2, 3)
               , Value = c("Discuss plan", "Discuss plan", "Discuss paln")
               , Value_Clean = c(NA, NA, "Discuss plan"))

Я хотел бы создать новый столбец с именем «Value_Final», в котором есть «Обсудить план» для идентификаторов 1, 2 и 3.

Мне кажется, довольно просто в состоянии выполнить sh это с помощью ifelse:

test$Value_Final <- ifelse(is.na(test$Value_Clean), test$Value, test$Value_Clean)

Однако, когда я делаю это, я получаю следующее:

> test
  ID        Value  Value_Clean Value_Final
1  1 Discuss plan         <NA>           2
2  2 Discuss plan         <NA>           2
3  3 Discuss paln Discuss plan           1

Какого черта? Я чувствую, что я делал подобные вещи с ifelse в R, не сталкиваясь с этой проблемой, так что же происходит?

Спасибо!

Ответы [ 3 ]

5 голосов
/ 28 февраля 2020

Это случай factor приведения к целочисленному значению хранилища. Может быть исправлено с помощью stringsAsFactors = FALSE при создании data.frame

test <- data.frame(ID = c(1, 2, 3)
                , Value = c("Discuss plan", "Discuss plan", "Discuss paln")
                , Value_Clean = c(NA, NA, "Discuss plan"), stringsAsFactors = FALSE)
ifelse(is.na(test$Value_Clean), test$Value, test$Value_Clean)
#[1] "Discuss plan" "Discuss plan" "Discuss plan"

или, если данные уже созданы, может быть преобразовано в character с помощью as.character

test[1:2] <- lapply(test[1:2], as.character)

Или сделать это в пределах ifelse

ifelse(is.na(test$Value_Clean), as.character(test$Value), 
         as.character(test$Value_Clean))
3 голосов
/ 28 февраля 2020

dplyr-версия ifelse не имеет этой проблемы

ifelse(is.na(test$Value_Clean), test$Value, test$Value_Clean)

# [1] 2 2 1


dplyr::if_else(is.na(test$Value_Clean), test$Value, test$Value_Clean)

# [1] Discuss plan Discuss plan Discuss plan
# Levels: Discuss paln Discuss plan

К вашему сведению, для данного конкретного примера вы можете использовать вместо coalesce

dplyr::coalesce(test$Value_Clean, test$Value)
# [1] Discuss plan Discuss plan Discuss plan
# Levels: Discuss plan
1 голос
/ 28 февраля 2020

вы можете попробовать dplyr и tibbles в качестве альтернативы:

library(dplyr)

tibble(ID = c(1, 2, 3)
       , Value = c("Discuss plan", "Discuss plan", "Discuss plan")
       , Value_Clean = c(NA, NA, "Discuss plan")) %>% 
  mutate(Value_Final = ifelse(is.na(Value_Clean), Value, Value_Clean))

тиблы не преобразуют символьные столбцы в коэффициенты по умолчанию, что очень удобно во многих случаях

Редактировать: используйте as_tibble(dataframe) для преобразования существующего кадра данных в таблицу

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...