Convert a chr time in to actuall time in R - r

so I'm trying to convert a F1 Laptime that is written in a chr in to time which I can then plot into a histogram.
This is what i tried. But with no success.
lapTimes <- lapTimes %>% mutate(Time = ms(Time))
format(as.POSIXct(lapTimes$time, tz = ""), format = "%M:%S.%OS")
The time always looks like this 1:11.111, with minutes first then secunds and then milliseconds.
If anyone has a idea I would greatly apprichiate that.
Thanks in advance! :D

As stated previously, I am assuming your data looks something like this:
laptime <- c("1:11.111", "2:02.2222")
What this represents is a time interval not a date time. As such you can convert this to a difftime class and then to numeric if needed.
as.difftime(laptime, format = "%M:%S.%OS")
#Time differences in mins
#[1] 1.183333 2.033333

since you provided no example data, I assumed it is stored as a character.
laptime <- "1:11.111"
> as.POSIXlt.character(laptime, format = "%M:%S.%OS", tz = 'GMT')
[1] "2021-01-14 00:01:11 GMT"
# compute time difference from dates
laptime <- "1:11.111"
t2 <- as.POSIXlt.character(laptime, format = "%M:%S.%OS", tz = 'GMT')
t1 <- as.Date(t2)
> difftime(t2, t1)
Time difference of 1.183333 mins
You could also take a look at this link, looks very useful for your specific problem: https://rstudio-pubs-static.s3.amazonaws.com/276999_042092be8e31414f82ef4f41e31fe5c8.html

Related

How can I extract a specific range of hours from a dataframe in R

I have a data frame in R with 2 columns (date_time , temp) I want to extract all the temp for the day time (between 5:59 Am to 18:00 Pm). I firstly separated date and times(hours) with this code:
Th$Hours <- format(as.POSIXct(Th$`date`,
"%Y-%m-%d %H:%M:%S", tz = ""),
format = "%H:%M")%>% as_tibble()
Th$Dates <- format(as.Date(Th$`date`,"%Y-%m-%d",
tz = ""), format = "%Y-%m-%d")%>% as_tibble()
and then I use following command to extract specific times:
Th_day<- Th[Th$Hours >= " 06:00 AM" & Th$Hours<= "18:00 PM",]%>% as_tibble()
But I get a tibble that give rows from 00:00 to 18:00 for every day :
What is the problem ?
Don't separate out the date from the time. When you use format to get the time, you are converting it to a character class, that doesn't know how to do time-based comparisons with > and <.
Instead, use hour to extract the hour component as an integer, and do comparisons on that:
library(lubridate)
Th %>%
mutate(DateTime <- as.POSIXct(date, "%Y-%m-%d %H:%M:%S", tz = "")) %>%
filter(hour(DateTime) >= 6 & hour(DateTime ) < 18)
I'm making some assumptions about your data structure - if you need more help than this please edit your question to share some sample data with dput() as the commenters have requested. dput(Th[1:5, ]) should be plenty.
Note that if you want to do a lot of operations on just the times (ignoring the date part), you could use the times class from the chron package, see here for some more info.

Adding milliseconds to a timestamp in R, even though the original character does not have milliseconds?

I am doing some animal movement analysis and I want to submit data to an organisation called Movebank for annotation, but they require the timestamp to have milliseconds included with 3 decimal places.
I have a column in my data frame (dat) with my timestamps as characters (without milliseconds), for example "2017-07-19 16:30:24"
To convert them to time and date format with milliseconds I am using the code:
options(digits.secs = 3)
dat$timestamp <- as.POSIXct(dat$timestamp, format = "%Y-%m-%d %H:%M:%OS", tz = "UTC")
Which works fine at converting my timestamp column to POSIXct which I can use to make tracks etc., but it does not add .000 milliseconds to the end of each timestamp which I was hoping it would.
I have also tried:
dat$timestamp <- as.POSIXct(dat$timestamp, format = "%Y-%m-%d %H:%M:%OS3", tz = "UTC")
(Note: I added .. %OS3 ...)
But this returns an NA for my for my timestamps.
Can anybody shed some light on this? I essentially need to add .000 to the end of each of my timestamps so that, using the example given above, I would have the format "2017-07-19 16:30:24.000"
The milliseconds will be dropped if there are no times with effective milliseconds.
options(digits.secs=4)
x1 <- as.POSIXct("2017-07-19 16:30:25")
as.POSIXct(paste0(x1, ".000"), format="%Y-%m-%d %H:%M:%OS")
# [1] "2017-07-19 16:30:25 UTC"
However, they will be added automatically if there are.
x2 <- as.POSIXct("2017-07-19 16:30:25.002")
c(x1, x2)
# [1] "2017-07-19 18:30:25.000 CEST" "2017-07-19 18:30:25.002 CEST"

Extract time from timestamp?

Essentially, I want only the hour, minute, and seconds from a column of timestamps I have in R, because I want to view how often different data points occur throughout different times of day and day and date is irrelevant.
However, this is how the timestamps are structured in the dataset:
2008-08-07T17:07:36Z
And I'm unsure how to only get that time from this timestamp.
Thank you for any help you can provide and please just let me know if I can provide more information!
We can use strptime to convert to a datetime class and then format to extract the hour:min:sec.
dtime <- strptime(str1, "%Y-%m-%dT%H:%M:%SZ")
format(dtime, "%H:%M:%S")
#[1] "17:07:36"
If the OP wants to have the hour, min, sec as separate columns
read.table(text=format(dtime, "%H:%M:%S"), sep=":", header=FALSE)
# V1 V2 V3
#1 17 7 36
Another option is using lubridate
library(lubridate)
format(ymd_hms(str1), "%H:%M:%S")
#[1] "17:07:36"
data
str1 <- "2008-08-07T17:07:36Z"
Just
x <- '2008-08-07T17:07:36Z'
substr(x, 12, 19)
#[1] "17:07:36"
...will do it if the timestamp is consistent, which I imagine it would be given it is an ISO_8601 ( https://en.wikipedia.org/wiki/ISO_8601 ) string.
I think you are expecting this...
Sys.time()
[1] "2016-04-19 11:09:30 IST"
format(Sys.time(),format = '%T')
[1] "11:09:30"
if you want to give your own timestamp, then use bellow code:
format(as.POSIXlt("2016-04-19 11:02:22 IST"),format = '%T')
[1] "11:02:22"
A regular expression will probably be quite efficient for this:
x <- '2008-08-07T17:07:36Z'
x
## [1] "2008-08-07T17:07:36Z"
sub('.*T(.*)Z', '\\1', x)
## [1] "17:07:36"

How To Split a Date & Time Observation

I am just learning R and have come up against this.
I have the below time series observations,
10/08/2015 02:31:04.450
I want to split the date and the time to separate columns.
Do i need need to round the Milliseconds in time? if so how.
I have been looking at, data table, lubridate to try and figure it out. I looked at XTS but that seems to be more orientated to aggregation of dates.
Are they any existing packages in R that allows for this splitting? and what sort of argument would I use.
Any help would be much appreciated.
Using data.table it is very straight forward:
require(data.table)
x <- "10/08/2015 02:31:04.450"
IDateTime(strptime(x, "%d/%m/%Y %H:%M:%OS"))
gives you the following data.table
idate itime
1: 2015-08-10 02:31:04
x <- "10/08/2015 02:31:04.450"
temp <- strptime(x, "%d/%m/%Y %H:%M:%OS")
format(temp,"%H:%M:%S")
#[1] "02:31:04"
as.Date(temp)
#[1] "2015-08-10"
If you do not need the time part in character form you can add few steps
x <- "10/08/2015 02:31:04.450"
temp <- strptime(x, "%d/%m/%Y %H:%M:%OS")
library(chron)
chron(times = format(temp,"%H:%M:%S"))
#[1] 02:31:04
class(chron(times = format(temp,"%H:%M:%S")))
#[1] "times"
as.Date(temp)
# [1] "2015-08-10"
string_timeStamp = "10/08/2015 02:31:04.450"
parsed_timeStamp = strptime(string_timeStamp, "%d/%m/%Y %H:%M:%OS")
date_time_dataFrame = data.frame(date = cut(parsed_timeStamp, breaks = "days"),
time = format(parsed_timeStamp, "%H:%M:%OS" ))
For more formatting options, check ?strptime

Convert to the day and time of the year in R

I have data for more than 3 years. For each year I want to find the day corresponding to Jaunary 1 of that year. For example:
> x <- c('5/5/2007','12/31/2007','1/2/2008')
> #Convert to day of year (julian date) –
> strptime(x,"%m/%d/%Y")$yday+1
[1] 125 365 2
I want to know how to do the same thing but with time added. But I still get the day not time. Can anyone suggest what is the better way to find the julian date with date and time ?
> x1 <- c('5/5/2007 02:00','12/31/2007 05:58','1/2/2008 16:25')
> #Convert to day of year (julian date) –
> strptime(x1,"%m/%d/%Y %H:%M")$yday+1
[1] 125 365 2
Rather than this result, I want the output in decimal days. For example the first example would be 125.0833333 and so on.
Thank you so much.
Are you hoping to get the day + a numerical part of a day as output? If so, something like this will work:
test <- strptime(x1,"%m/%d/%Y %H:%M")
(test$yday+1) + (test$hour/24) + (test$min/(24*60))
#[1] 125.083333 365.248611 2.684028
Although this matches what you ask for, I think removing the +1 might make more sense:
(test$yday) + (test$hour/24) + (test$min/(24*60))
#[1] 124.083333 364.248611 1.684028
Though my spidey senses are tingling that Dirk is going to show up and show me how to do this with a POSIXct date/time representation.
Here is an attempt of such an answer using base functions:
mapply(julian, as.POSIXct(test), paste(format(test,"%Y"),"01","01",sep="-"))
#[1] 124.083333 364.248611 1.684028
You can also use POSIXct and POSIXlt representations along with firstof function from xts.
x1 <- c("5/5/2007 02:00", "12/31/2007 05:58", "1/2/2008 16:25")
x1
## [1] "5/5/2007 02:00" "12/31/2007 05:58" "1/2/2008 16:25"
y <- as.POSIXlt(x1, format = "%m/%d/%Y %H:%M")
result <- mapply(julian, x = as.POSIXct(y), origin = firstof(y$year + 1900))
result
## [1] 124.083333 364.248611 1.684028
if you don't want to use xts then perhaps something like this
result <- mapply(julian,
x = as.POSIXct(x1, format = "%m/%d/%Y %H:%M", tz = "GMT"),
origin = as.Date(paste0(gsub(".*([0-9]{4}).*", "\\1", x1),
"-01-01"),
tz = "GMT"))
result
## [1] 124.083333 364.248611 1.684028
If you want to do the other way around (convert day of the year to date and time), you can use this little function:
doy2date = function(mydoy){
mydate = as.Date(mydoy, origin = "2008-01-01 00:00:00", tz = "GMT")
dech = (mydoy - as.integer(mydoy)) * 24
myh = as.integer(dech)
mym = as.integer( (dech - as.integer(dech)) * 60)
mys = round(I( (((dech - as.integer(dech)) * 60) - mym) * 60), digits=0 )
posixdate = as.POSIXct(paste(mydate, " ", myh,":",mym,":",mys, sep=""), tz = "GMT")
return(posixdate)
}
As an example, if you try:
doy2date(117.6364)
The function will return "2008-04-27 15:16:25 GMT" as a POSIXct.

Resources