Keep format after using ifelse in R

Problem with different format after using ifelse in R

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.





Posted

in

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *