2

I need help. I am trying to copy the date_time column values into new column based on matching values of txt_col column and those that are not matched mark as NA. Here is my code:

df$new_col <- ifelse(df$txt_col == "apple", df$date_time, NA)

However, I get numbers in the new column, instead of date-time :

   new_col
1477962000
1451755980
1451755980
1451755980

When looking at the str(df), the column date_time is POSIXct. I tried to convert as.numeric and POSIXct, it didn't work. If you have more elegant ways to do what I am trying to achieve, it would be much appreciated if you share. Thank you.

Lilu
  • 108
  • 8
  • They are the numeric equivalent of the datetime - the number of seconds since 1970-01-01. Wrap the whole thing in an `as.POSIXct()` and you should be fine. – thelatemail Apr 17 '17 at 23:57
  • Don't forget to include a time zone when you wrap it again, processing gets very interesting when the tz changes mid-stream :-) – r2evans Apr 17 '17 at 23:58
  • `as.POSIXct(1477962000, origin = "1970-01-01 00:00:00")` works for me. – r2evans Apr 17 '17 at 23:59
  • @r2evans - `as.POSIXct(1477962000, origin = "1970-01-01")` for short – thelatemail Apr 17 '17 at 23:59
  • I've occasionally gone beyond "explicit", thanks. – r2evans Apr 18 '17 at 00:00
  • @r2evans and TheLateMail - Thank you! :) It does work when I separately wrap with POSIXct () on already newly generated column. But when I wrap it in the original ifelse operation, it still puts the numbers. – Lilu Apr 18 '17 at 00:10
  • One of the frustrations of `ifelse` is that it strips attributes, including class, which is where the numbers come from—they're how POSIXct is stored. You either need to reassign the class as suggested above, or find another approach that doesn't strip it in the first place. – alistaire Apr 18 '17 at 00:24
  • @alistaire thank you for your input. – Lilu Apr 18 '17 at 00:25
  • [Here's](http://stackoverflow.com/questions/32336773/why-dplyrs-mutate-changes-time-format/32337025#32337025) why. – Rich Scriven Apr 18 '17 at 00:27
  • @epi99 Thank you! This worked! :) – Lilu Apr 18 '17 at 00:27

1 Answers1

7

Package dplyr as a stricter function if_else that verifies the classes of both the true and false components. Explicitly providing the class for the NA value makes this more "type safe"

library(dplyr)
df <- data.frame(txt_col = c("apple", "apple", "orange"),
                 date_time = as.POSIXct(c("2017-01-01", "2017-01-02", "2017-01-03")))

# use dplyr::if_else instead, and provide explicit class
df$new_col <- if_else(df$txt_col == "apple", df$date_time, as.POSIXct(NA))

df
#   txt_col  date_time    new_col
# 1   apple 2017-01-01 2017-01-01
# 2   apple 2017-01-02 2017-01-02
# 3  orange 2017-01-03       <NA>
Andrew Lavers
  • 4,328
  • 1
  • 12
  • 19