Imran Ali
Imran Ali

Reputation: 2279

Converting character to date with time zone using looping functions

Given: A data frame with three character columns.

Date        Time    Zone
1950-04-18  01:30   CST
1950-04-18  01:45   CST
1951-02-20  16:00   CST
1951-06-08  09:00   CST
1951-11-15  15:00   CST
1951-11-15  20:00   CST

Required:
1. Combine Date, Time and, Zone
2. Convert from Character to Date

What I have tried:
1. datetime <- paste(Date, Time)
2. strptime(datetime[1], "%Y-%m-%d %H:%M", tz=Zone[1])

This successfully parses the first element, however, I would like to convert the entire data using one of the looping functions lapply or sapply.

How can I use loop functions to parse the entire vector?

NOTE: Forgot to mention earlier, the data contains various abbreviated time zones other than CST

Upvotes: 1

Views: 540

Answers (2)

Jaap
Jaap

Reputation: 83215

Timezones can be a tricky thing to handle as there are different formats being used. To get a list of the used timezones on your system, run OlsonNames() for the list.

The CST timezone you used in your example is not always supported and you might therefore get the following warning message when trying to use that as a timezone:

In as.POSIXct.POSIXlt(x) : unknown timezone 'CST'

I've constructed an example dataset (see below) to show how you can update your datetime with timezone information. The following for loop:

for (i in 1:nrow(d))
  d$datetime[i] <- strftime(paste(d$Date, d$Time)[i],
                            format="%Y-%m-%d %H:%M", 
                            tz = as.character(d$Zone[i]),
                            usetz = TRUE)

will give:

> d
        Date  Time Zone             datetime
1 1950-04-18 01:30  GMT 1950-04-18 01:30 GMT
2 1950-04-18 01:45  CET 1950-04-18 01:45 CET
3 1951-02-20 16:00  EET 1951-02-20 16:00 EET
4 1951-06-08 09:00  EST 1951-06-08 09:00 EST
5 1951-11-15 15:00  WET 1951-11-15 15:00 WET
6 1951-11-15 20:00  MST 1951-11-15 20:00 MST

As said, your dataset might contain timezone abbreviations that are not recognized by your system. You could replace these with the help of this list for example.


Used data:

d <- read.table(text="Date        Time    Zone
1950-04-18  01:30   GMT
1950-04-18  01:45   CET
1951-02-20  16:00   EET
1951-06-08  09:00   EST
1951-11-15  15:00   WET
1951-11-15  20:00   MST", header=TRUE, stringsAsFactors = FALSE)

Upvotes: 3

tushaR
tushaR

Reputation: 3116

I think this should work:

df1<-data.frame(x = paste(df$Date,df$Time), Zone =df$Zone)
d<-mapply(FUN = strptime,x=df1$x,tz=as.character(df1$Zone),format="%Y-%m-%d %H:%M",SIMPLIFY = F,USE.NAMES = F)

Upvotes: 0

Related Questions