Sometimes you might get results in a different format after using ifelse in R. Usually when returning NA in the results or something from a different data type. Here is how to fix that or use alternatives.
2 problems with ifelse
Ifelse is simple and function that is easy to use, but there might be some difficulties. Usually, in case if NA values are involved. You can get a problem with two of these.
Something that looks like R is ignoring the NA value or NA is not considered FALSE in the R function ifelse.
Here is my data frame with generated dates and text.
x <- data.frame('date' = seq(Sys.Date() - 5, Sys.Date(), by = "days"), 'text' = as.character(c( "good", "bad", "nothing", "good", "nothing", "good" ))) x # date text #1 2021-07-14 good #2 2021-07-15 bad #3 2021-07-16 nothing #4 2021-07-17 good #5 2021-07-18 nothing #6 2021-07-19 good
1. different format after ifelse: Date or DateTime as a number after using R ifelse
Let’s say I would like to replace one of the dates with NA.
x$date2 <- ifelse(x$date == Sys.Date() - 2, NA, x$date) knitr::kable(x) #|date |text | date2| #|:----------|:-------|-----:| #|2021-07-14 |good | 18822| #|2021-07-15 |bad | 18823| #|2021-07-16 |nothing | 18824| #|2021-07-17 |good | NA| #|2021-07-18 |nothing | 18826| #|2021-07-19 |good | 18827|
As you can see result looks like a bunch of numbers. You can convert that to date format by adding an origin of dates.
x$date2 <- as.Date(x$date2, origin = "1970-01-01") knitr::kable(x) #|date |text |date2 | #|:----------|:-------|:----------| #|2021-07-14 |good |2021-07-14 | #|2021-07-15 |bad |2021-07-15 | #|2021-07-16 |nothing |2021-07-16 | #|2021-07-17 |good |NA | #|2021-07-18 |nothing |2021-07-18 | #|2021-07-19 |good |2021-07-19 |
2. different format after ifelse: string as a number after using R ifelse
String after use of ifelse might appear in the form of a number. Here I would like to replace the word “nothing” with NA.
x$text2 <- ifelse(x$text == "nothing", NA, x$text) knitr::kable(x) #|date |text | text2| #|:----------|:-------|-----:| #|2021-07-14 |good | 2| #|2021-07-15 |bad | 1| #|2021-07-16 |nothing | NA| #|2021-07-17 |good | 2| #|2021-07-18 |nothing | NA| #|2021-07-19 |good | 2|
As a result of ifelse, I get a number instead of text. You can fix that by using as.character function when returning a column with strings.
x$text2 <- ifelse(x$text == "nothing", NA, as.character(x$text)) knitr::kable(x) #|date |text |text2 | #|:----------|:-------|:-----| #|2021-07-14 |good |good | #|2021-07-15 |bad |bad | #|2021-07-16 |nothing |NA | #|2021-07-17 |good |good | #|2021-07-18 |nothing |NA | #|2021-07-19 |good |good |
Use R ifelse alternatives
Try to use function replace.
x$date2 <- replace(x$date, x$date == Sys.Date()-2, NA) x$text2 <- replace(x$text, x$text == "nothing", NA) x #|date |text |date2 |text2 | #|:----------|:-------|:----------|:-----| #|2021-07-14 |good |2021-07-14 |good | #|2021-07-15 |bad |2021-07-15 |bad | #|2021-07-16 |nothing |2021-07-16 |NA | #|2021-07-17 |good |NA |good | #|2021-07-18 |nothing |2021-07-18 |NA | #|2021-07-19 |good |2021-07-19 |good |
You can use case_when from the dplyr like ifelse but with one returning value.
You should adjust the previously used statement, and it does a good job.
require(dplyr) x <- x %>% mutate(date2 = case_when(x$date != Sys.Date()-2 ~ x$date)) x <- x %>% mutate(text2 = case_when(x$text != "nothing" ~ x$text)) knitr::kable(x) #|date |text |date2 |text2 | #|:----------|:-------|:----------|:-----| #|2021-07-14 |good |2021-07-14 |good | #|2021-07-15 |bad |2021-07-15 |bad | #|2021-07-16 |nothing |2021-07-16 |NA | #|2021-07-17 |good |NA |good | #|2021-07-18 |nothing |2021-07-18 |NA | #|2021-07-19 |good |2021-07-19 |good |
If you have multiple, nested ifelse statements, then case_when from the dplyr package might be what you’re looking for.
Here is how to easily apply R ifelse to multiple columns in the data frame.
Function ifelse might be a good way how to go from Excel to R. Read about that here.
Leave a Reply