How to create a time from a POSIXct - r

I have some dates in POSIXct format
head(data$Dates,3)
[1] "2015-01-02 16:34:01 GMT" "2015-01-28 16:33:03 GMT" "2015-01-16 20:55:35 GMT"
And I would like to create a column that is the DATE of each element with the time of 21:00:00 GMT and then subtract this new date from the original.
So from that vector of dates I want to create a vector of POSIXct that looks like
"2015-01-02 21:00:00 GMT" "2015-01-28 21:00:00 GMT" "2015-01-16 21:00:00 GMT"
Then I want to subtract this new vector from the first one.
How do I create the vector that looks like:
"2015-01-02 21:00:00 GMT" "2015-01-28 21:00:00 GMT" "2015-01-16 21:00:00 GMT"
Thank you.

I recommend using the lubridate package. It will enable you to subtract dates from each other. Do you want to set the time to be the same thing for each one as an intermediary step in date subtraction? Slicing the first part of the timestamp to just get the date, using something like:
clean_date <- function(date){
date = substr(date, 1, 10)
return(date)
}
df$Date <- clean_date(df$Date)
and then just converting that to a lubridate date object, using
df$Date <- ymd(date)
should allow you to find the difference between the two dates easily, and will create a difftime object that will give you the the differenced between the two dates in your chosen unit.

It's not entirely clear if this is the type of result you are going after, but this should get you started.
dates <- as.POSIXct(c("2015-01-02 16:34:01 GMT",
"2015-01-28 16:33:03 GMT",
"2015-01-16 20:55:35 GMT"))
library(lubridate)
orig_dates <- ymd_hms(dates)
trunc_dates <- floor_date(orig_dates, "day")
trunc_dates_21st_hour <- trunc_dates + ehours(21)
orig_dates - trunc_dates_21st_hour
# Time differences in mins
# [1] -265.983333 -266.950000 -4.416667

Related

Two Timestamp Formats in R

Im have a time stamp column that I am converting into a POSIXct. The problem is that there are two different formats in the same column, so if I use the more common conversion the other gets converted into NA.
MC$Date
12/1/15 22:00
12/1/15 23:00
12/2/15
12/2/15 1:00
12/2/15 2:00
I use the following code to convert to a POSIXct:
MC$Date <- as.POSIXct(MC$Date, tz='MST', format = '%m/%d/%Y %H:%M')
The results:
MC$Date
15-12-01 22:00:00
15-12-01 23:00:00
NA
15-12-02 01:00:00
15-12-02 02:00:00
I have tried using a logic vector to identify the issue then correct it but can't find an easy solution.
The lubridate package was designed to deal with situations like this.
dt <- c(
"12/1/15 22:00",
"12/1/15 23:00",
"12/2/15",
"12/2/15 1:00",
"12/2/15 2:00"
)
dt
[1] "12/1/15 22:00" "12/1/15 23:00" "12/2/15" "12/2/15 1:00" "12/2/15 2:00"
lubridate::mdy_hm(dt, truncated = 2)
[1] "2015-12-01 22:00:00 UTC" "2015-12-01 23:00:00 UTC" "2015-12-02 00:00:00 UTC"
[4] "2015-12-02 01:00:00 UTC" "2015-12-02 02:00:00 UTC"
The truncated parameter indicates how many formats can be missing.
You may add the tz parameter to specify which time zone to parse the date with if UTC is not suitable.
I think the logic vector approach could work. Maybe in tandem with an temporary vector for holding the parsed dates without clobbering the unparsed ones. Something like this:
dates <- as.POSIXct(MC$Date, tz='MST', format = '%m/%d/%Y %H:%M')
dates[is.na(dates)] <- as.POSIXct(MC[is.na(dates),], tz='MST', format = '%m/%d/%Y')
MC$Date <- dates
Since all of your datetimes are separated with a space between date and time, you could use strsplit to extract only the date part.
extractDate <- function(x){ strsplit(x, split = " " )[[1]][1] }
MC$Date <- sapply( MC$Date, extractDate )
Then go ahead and convert any way you like, without worrying about the time part getting in the way.

convert character string with no correct format to posixct

I have downloaded some climate reanalysis data, which took a lot of time to convert from grib, to cdf and finally now I've managed to make it work in R. The next issue I have is that time is a character vector, similar to the following:
tt =c(
"20090101","20090101.25","20090101.5","20090101.75","20090102",
"20090102.25","20090102.5","20090102.75","20090103","20090103.25",
"20090103.5","20090103.75","20090104","20090104.25","20090104.5",
"20090104.75")
where the first four digits are the year, followed by month, then day, and finally fraction of the day: yyyymmdd...
How can I convert this to posixct time with a format yyyy-mm-dd HH:MM?
I would try
as.POSIXct(tt,'%Y%m%d')
but this wont help here due to the day fraction.
The final result should be:
tt
[1] "2009-01-01 00:00" "2009-01-01 06:00" "2009-01-01 12:00"
"2009-01-01 18:00" "2009-01-02 00:00"
Can anyone suggest a solution?
Note: I can get half of the way with
as.Date(tt, "%Y%m%d")
but not sure what to do with the fraction
Starting with:
tt=c("20090101" , "20090101.25" ,"20090101.5" , "20090101.75" ,"20090102")
convert the date part and then extract the fractional part and add as a fraction of the day in seconds:
as.POSIXct(tt,format="%Y%m%d") + (as.numeric(tt) - as.integer(tt))*(60*60*24)
[1] "2009-01-01 00:00:00 GMT" "2009-01-01 06:00:00 GMT"
[3] "2009-01-01 12:00:00 GMT" "2009-01-01 18:00:00 GMT"
[5] "2009-01-02 00:00:00 GMT"

Convert julian time into date in R

I am trying to convert an array of Julian time into the standard Gregorian calendar. For that, I am using chron, which seems quite simple. The problem is that the origin does not fit with the beginning of the time. That means, I know the date starts at 12:00:00 in 23 May 2014 and end at 5th Sep 2014 at 7am. Then, if I use chron as the following:
#The first 50 values
time <- dput(t[1:50])
structure(c(143.0208333, 143.0416667, 143.0625, 143.0833333,
143.1041667, 143.125, 143.1458333, 143.1666667, 143.1875, 143.2083333,
143.2291667, 143.25, 143.2708333, 143.2916667, 143.3125, 143.3333333,
143.3541667, 143.375, 143.3958333, 143.4166667, 143.4375, 143.4583333,
143.4791667, 143.5, 143.5208333, 143.5416667, 143.5625, 143.5833333,
143.6041667, 143.625, 143.6458333, 143.6666667, 143.6875, 143.7083333,
143.7291667, 143.75, 143.7708333, 143.7916667, 143.8125, 143.8333333,
143.8541667, 143.875, 143.8958333, 143.9166667, 143.9375, 143.9583333,
143.9791667, 144, 144.0208333, 144.0416667), .Dim = 50L)
#Convert into GCalen.
newtime <- chron(time, origin=c(month = 1, day = 1, year = 2014))
dates <- as.POSIXlt(newt, "GMT")
The dates start at:
"2014-05-24 00:29:59 GMT" "2014-05-24 01:00:00 GMT" "2014-05-24 01:30:00 GMT" "2014-05-24 01:59:59 GMT"....
Looking into the end of the dates, I would have the same problem, because it finishes at "2014-09-06 07:30:00 GMT", one day later ..so there is a substantial lapse that it needs to be fixed.
is there any way to add in the origin the time?? hour:min:sg??

R format date with time stamp

I would like to convert the following dates
dates <-c(1149318000L, 1151910000L, 1154588400L, 1157266800L, 1159858800L, 1162540800L)
into date and time format
I don't know the origin of the date but I know that
1146685218 = 2006/05/03 07:00:00
** Update 1 **
I have sorted the unformatted dates and replace the sample above with a friendly sequence but I have real dates. I was thinking of using the the above key as origin, but It does not seem to work.
let
seconds_in_days <- 3600*24
(dates[2]-dates[1])/seconds_in_days
## [1] 30
If you know
1146685218 = 2006/05/03 07:00:00
then just make that the origin
dates <- c(1149318000L, 1151910000L, 1154588400L, 1157266800L, 1159858800L, 1162540800L)
orig.int <- 1146685218
orig.date <- as.POSIXct("2006/05/03 07:00:00", format="%Y/%m/%d %H:%M:%S")
as.POSIXct(dates-orig.int, origin=orig.date)
# [1] "2006-06-02 18:19:42 EDT" "2006-07-02 18:19:42 EDT" "2006-08-02 18:19:42 EDT"
# [4] "2006-09-02 18:19:42 EDT" "2006-10-02 18:19:42 EDT" "2006-11-02 18:19:42 EST"
This works assuming your "date" values are the number of seconds since a particular date/time which is how POSIXt stores it's date/time values.

Extracting time from POSIXct

How would I extract the time from a series of POSIXct objects discarding the date part?
For instance, I have:
times <- structure(c(1331086009.50098, 1331091427.42461, 1331252565.99979,
1331252675.81601, 1331262597.72474, 1331262641.11786, 1331269557.4059,
1331278779.26727, 1331448476.96126, 1331452596.13806), class = c("POSIXct",
"POSIXt"))
which corresponds to these dates:
"2012-03-07 03:06:49 CET" "2012-03-07 04:37:07 CET"
"2012-03-09 01:22:45 CET" "2012-03-09 01:24:35 CET"
"2012-03-09 04:09:57 CET" "2012-03-09 04:10:41 CET"
"2012-03-09 06:05:57 CET" "2012-03-09 08:39:39 CET"
"2012-03-11 07:47:56 CET" "2012-03-11 08:56:36 CET"
Now, I have some values for a parameter measured at those times:
val <- c(1.25343125e-05, 0.00022890575,
3.9269125e-05, 0.0002285681875,
4.26353125e-05, 5.982625e-05,
2.09575e-05, 0.0001516951251,
2.653125e-05, 0.0001021391875)
I would like to plot val vs time of the day, irrespectively of the specific day when val was measured.
Is there a specific function that would allow me to do that?
You can use strftime to convert datetimes to any character format:
> t <- strftime(times, format="%H:%M:%S")
> t
[1] "02:06:49" "03:37:07" "00:22:45" "00:24:35" "03:09:57" "03:10:41"
[7] "05:05:57" "07:39:39" "06:47:56" "07:56:36"
But that doesn't help very much, since you want to plot your data. One workaround is to strip the date element from your times, and then to add an identical date to all of your times:
> xx <- as.POSIXct(t, format="%H:%M:%S")
> xx
[1] "2012-03-23 02:06:49 GMT" "2012-03-23 03:37:07 GMT"
[3] "2012-03-23 00:22:45 GMT" "2012-03-23 00:24:35 GMT"
[5] "2012-03-23 03:09:57 GMT" "2012-03-23 03:10:41 GMT"
[7] "2012-03-23 05:05:57 GMT" "2012-03-23 07:39:39 GMT"
[9] "2012-03-23 06:47:56 GMT" "2012-03-23 07:56:36 GMT"
Now you can use these datetime objects in your plot:
plot(xx, rnorm(length(xx)), xlab="Time", ylab="Random value")
For more help, see ?DateTimeClasses
The data.table package has a function 'as.ITime', which can do this efficiently use below:
library(data.table)
x <- "2012-03-07 03:06:49 CET"
as.IDate(x) # Output is "2012-03-07"
as.ITime(x) # Output is "03:06:49"
There have been previous answers that showed the trick. In essence:
you must retain POSIXct types to take advantage of all the existing plotting functions
if you want to 'overlay' several days worth on a single plot, highlighting the intra-daily variation, the best trick is too ...
impose the same day (and month and even year if need be, which is not the case here)
which you can do by overriding the day-of-month and month components when in POSIXlt representation, or just by offsetting the 'delta' relative to 0:00:00 between the different days.
So with times and val as helpfully provided by you:
## impose month and day based on first obs
ntimes <- as.POSIXlt(times) # convert to 'POSIX list type'
ntimes$mday <- ntimes[1]$mday # and $mon if it differs too
ntimes <- as.POSIXct(ntimes) # convert back
par(mfrow=c(2,1))
plot(times,val) # old times
plot(ntimes,val) # new times
yields this contrasting the original and modified time scales:
Here's an update for those looking for a tidyverse method to extract hh:mm::ss.sssss from a POSIXct object. Note that time zone is not included in the output.
library(hms)
as_hms(times)
Many solutions have been provided, but I have not seen this one, which uses package chron:
hours = times(strftime(times, format="%T"))
plot(val~hours)
(sorry, I am not entitled to post an image, you'll have to plot it yourself)
I can't find anything that deals with clock times exactly, so I'd just use some functions from package:lubridate and work with seconds-since-midnight:
require(lubridate)
clockS = function(t){hour(t)*3600+minute(t)*60+second(t)}
plot(clockS(times),val)
You might then want to look at some of the axis code to figure out how to label axes nicely.
The time_t value for midnight GMT is always divisible by 86400 (24 * 3600). The value for seconds-since-midnight GMT is thus time %% 86400.
The hour in GMT is (time %% 86400) / 3600 and this can be used as the x-axis of the plot:
plot((as.numeric(times) %% 86400)/3600, val)
To adjust for a time zone, adjust the time before taking the modulus, by adding the number of seconds that your time zone is ahead of GMT. For example, US central daylight saving time (CDT) is 5 hours behind GMT. To plot against the time in CDT, the following expression is used:
plot(((as.numeric(times) - 5*3600) %% 86400)/3600, val)

Resources