Converting a column in R to type datetime: as.POSIXct returns NA

Viewed 282

I am struggling while trying to convert a column of type char to datetime.

 Date.Time  Lat Lon Base
<chr>   <dbl>   <dbl>   <chr>
4/1/2014 0:11:00    40.7690 -73.9549    B02512
4/1/2014 0:17:00    40.7267 -74.0345    B02512
4/1/2014 0:21:00    40.7316 -73.9873    B02512
⋮   ⋮   ⋮   ⋮
4/30/2014 23:31:00  40.7443 -73.9889    B02764
4/30/2014 23:32:00  40.6756 -73.9405    B02764
4/30/2014 23:48:00  40.6880 -73.9608    B02764

Using mutate:

df <- mutate(df, Date.Time = as.POSIXct(Date.Time,
                 format = "%M/%D%/%Y% %H:%M%S"))

While the type for Date.Time has changed from to , the whole column is just NAs.

Output of Sys.getlocale():

'LC_CTYPE=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=C;LC_COLLATE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_MESSAGES=C;LC_PAPER=en_US.UTF-8;LC_NAME=C;LC_ADDRESS=C;LC_TELEPHONE=C;LC_MEASUREMENT=en_US.UTF-8;LC_IDENTIFICATION=C'
4 Answers

Your input formatting codes are not correct. Should be "%m/%d/%Y %H:%M:%S" instead of "%M/%D%/%Y% %H:%M%S". Everything else is fine:

library(dplyr)

df <- read.table(header = TRUE, text = '
 Date.Time          Lat     Lon         Base
"4/1/2014 0:11:00"    40.7690 -73.9549    B02512
"4/1/2014 0:17:00"    40.7267 -74.0345    B02512
"4/1/2014 0:21:00"    40.7316 -73.9873    B02512
"4/30/2014 23:31:00"  40.7443 -73.9889    B02764
"4/30/2014 23:32:00"  40.6756 -73.9405    B02764
"4/30/2014 23:48:00"  40.6880 -73.9608    B02764')

df2 <- mutate(df, Date.Time = as.POSIXct(Date.Time, 
                                        format = "%m/%d/%Y %H:%M:%S"))

str(df2)
# 'data.frame': 6 obs. of  4 variables:
#   $ Date.Time: POSIXct, format: "2014-04-01 00:11:00" "2014-04-01 00:17:00" "2014-04-01 00:21:00" ...
# $ Lat      : num  40.8 40.7 40.7 40.7 40.7 ...
# $ Lon      : num  -74 -74 -74 -74 -73.9 ...
# $ Base     : chr  "B02512" "B02512" "B02512" "B02764" ...

You can use the library anytime to do this. Here is an example -

date_var = "4/30/2014"

library(anytime)
anytime::anydate(date_var)

results in

> "2014-04-30"

An option with lubridate

library(dplyr)
library(lubridate)
df %>% 
  mutate(Date.Time = mdy_hms(Date.Time))

Actually, your attempt is quite correct, only the format was wrong.

as.POSIXct("4/1/2014 0:21:00", format = "%M/%D%/%Y% %H:%M%S")
#> [1] NA

If you remove the extra % after year and day, add the missing : between minutes and seconds and make the codes for year and month a lower case letter (because %M stands for minutes and %D is short for %m/%d/%y::

as.POSIXct("4/1/2014 0:21:00", format = "%m/%d/%Y %H:%M:%S")
#> [1] "2014-04-01 00:21:00 CEST"

Created on 2021-02-14 by the reprex package (v1.0.0)

Related