How to change Time format in R? - r

I have added a new column RIDE_LENGTH using mutate function as follows.
df2 <- mutate(df2, RIDE_LENGTH = (ENDED_AT - STARTED_AT)
ENDED AT & STARTED AT is in HH:MM:SS format, but my new column is showing the result in seconds only
example : 12:05:00 - 12:03:00 = 120 secs.
I need the answer to be in the same format as 00:02:00.
If anyone can tell me how to do that would be a great help.

You can use
library(lubridate)
RIDE_LENGTH <- seconds_to_period(RIDE_LENGTH)

There are a few ways in the lubridate package, depending on your desired output. Take your pick:
library(dplyr)
df <- data.frame(
STARTED_AT = as.POSIXct("2022-06-06 12:03:00 UTC"),
ENDED_AT = as.POSIXct("2022-06-06 12:05:00 UTC")
)
df |>
mutate(
RIDE_LENGTH_base = ENDED_AT - STARTED_AT,
RIDE_LENGTH_lubridate_difftime = lubridate::as.difftime(ENDED_AT - STARTED_AT),
RIDE_LENGTH_period = lubridate::as.period(ENDED_AT - STARTED_AT),
RIDE_LENGTH_duration = lubridate::as.duration(ENDED_AT - STARTED_AT)
)
# STARTED_AT ENDED_AT RIDE_LENGTH_base RIDE_LENGTH_lubridate_difftime RIDE_LENGTH_period RIDE_LENGTH_interval
# 1 2022-06-06 12:03:00 2022-06-06 12:05:00 2 mins 2 mins 2M 0S 120s (~2 minutes)

Related

Converting character to dates with hours and minutes

I'm having trouble converting character values into date (hour + minutes), I have the following codes:
start <- c("2022-01-10 9:35PM","2022-01-10 10:35PM")
end <- c("2022-01-11 7:00AM","2022-01-11 8:00AM")
dat <- data.frame(start,end)
These are all in character form. I would like to:
Convert all the datetimes into date format and into 24hr format like: "2022-01-10 9:35PM" into "2022-01-10 21:35",
and "2022-01-11 7:00AM" into "2022-01-11 7:00" because I would like to calculate the difference between the dates in hrs.
Also I would like to add an ID column with a specific ID, the desired data would like this:
ID <- c(101,101)
start <- c("2022-01-10 21:35","2022-01-10 22:35")
end <- c("2022-01-11 7:00","2022-01-11 8:00")
diff <- c(9,10) # I'm not sure how the calculations would turn out to be
dat <- data.frame(ID,start,end,diff)
I would appreciate all the help there is! Thanks!!!
You can use lubridate::ymd_hm. Don't use floor if you want the exact value.
library(dplyr)
library(lubridate)
dat %>%
mutate(ID = 101,
across(c(start, end), ymd_hm),
diff = floor(end - start))
start end ID diff
1 2022-01-10 21:35:00 2022-01-11 07:00:00 101 9 hours
2 2022-01-10 22:35:00 2022-01-11 08:00:00 101 9 hours
The base R approach with strptime is:
strptime(dat$start, "%Y-%m-%d %H:%M %p")
[1] "2022-01-10 09:35:00 CET" "2022-01-10 10:35:00 CET"

changing date/time variable to time that starts at 00:00:00 in r

I'm looking for a simple and correct way to change the date/time (POSIXct) format into a time that starts at 00:00:00.
I couldn't find an answer to this in R language, but if I overlooked one, please tell me :)
So I have this :
date/time
v1
2022-02-16 15:07:15
38937
2022-02-16 15:07:17
39350
And I would like this :
time
v1
00:00:00
38937
00:00:02
39350
Can somebody help me with this?
Thanks :)
You can calculate the difference between the two datetimes in seconds, and add i to a random date starting at "00:00:00", before formatting it to only including the time. See the time column in the reprex underneath:
library(dplyr)
ibrary(lubridate)
df %>%
mutate(
date = lubridate::ymd_hms(date),
seconds = as.numeric(date - first(date)),
time = format(
lubridate::ymd_hms("2022-01-01 00:00:00") + seconds,
format = "%H:%M:%S"
)
)
#> # A tibble: 2 × 4
#> date v1 seconds time
#> <dttm> <dbl> <dbl> <chr>
#> 1 2022-02-16 15:07:15 38937 0 00:00:00
#> 2 2022-02-16 15:07:17 39350 2 00:00:02
Created on 2022-03-30 by the reprex package (v2.0.1)
Note that this will be misleading if you ever have over 24 hours between two datetimes. In these cases you should probably include the date.
Data
df <- tibble::tribble(
~date, ~v1,
"2022-02-16 15:07:15", 38937,
"2022-02-16 15:07:17", 39350
)
You can deduct all date/time with the first record of date/time, and change the result to type of time by the hms() function in the hms package.
library(dplyr)
library(hms)
df %>%
mutate(`date/time` = hms::hms(as.numeric(as.POSIXct(`date/time`) - as.POSIXct(first(`date/time`)))))
date/time v1
1 00:00:00 38937
2 00:00:02 39350
Note that in this method, even if the time difference is greater than 1 day, it'll be reflected in the result, for example:
df <- read.table(header = T, check.names = F, sep = "\t", text = "
date/time v1
2022-02-16 15:07:15 38937
2022-02-18 15:07:17 39350")
df %>%
mutate(`date/time` = hms::hms(as.numeric(as.POSIXct(`date/time`) - as.POSIXct(first(`date/time`)))))
date/time v1
1 00:00:00 38937
2 48:00:02 39350

Rounding up the time expression in R

I have a data Y . Y has a column time .
time column looks like this:
For example, 20211201000010 means 2021-12-01 00:00:10 .
time <- strptime(Y$time, format = "%Y%m%d%H%M%S")
start_time <- min(time)
In this code, start_time is 2021-12-01 00:00:02.
But I want to round up the start_timeas 2021-12-01 00:00:10,since the start_time should be 10 seconds interval for my data.
How can I round up 2021-12-01 00:00:02 as 2021-12-01 00:00:10 ?
lubridate package is always our friends for datetime work.
library(lubridate)
xx1 <- '20211201010002'
ymd_hms(xx1) %>%
ceiling_date(unit = '10s')
[1] "2021-12-01 01:00:10 UTC"
You may need to calculate the remainder (divide by 10) before you format the data.
e.g.
20211201000002 %% 10 = 2;
20211201000010 %% 10 = 0
Then you find the first 0 in your list.

Separating date and time from timestamp

I have looked at different options from previous answers, but none has given me the correct output.
I would like to separate timestamp into date and time using R
sorted_transactions_table$TRANSACTION_DATE <- as.Date(sorted_transactions_table$TRANSACTION_TIME)
I have tried this but I get an error:
Error in charToDate(x) : character string is not in a standard
unambiguous format
Timestamp from my dataset is in the format:
01-OCT-18 12.01.23.000000 AM
Convert it into standard datetime format first and then use format
df$TRANSACTION_DATE <- as.POSIXct(df$TRANSACTION_DATE,
format = "%d-%b-%y %H.%M.%OS %p")
transform(df, Date = as.Date(TRANSACTION_DATE),
#Also Date = format(TRANSACTION_DATE, "%Y-%m-%d") would work
time = format(TRANSACTION_DATE, "%T"))
# col1 TRANSACTION_DATE Date time
#1 1 2018-10-01 12:01:23 2018-10-01 12:01:23
#2 2 2018-10-01 12:02:23 2018-10-01 12:02:23
#3 3 2018-10-01 12:03:23 2018-10-01 12:03:23
You could also do this in dplyr chain
library(dplyr)
df %>%
mutate(TRANSACTION_DATE = as.POSIXct(TRANSACTION_DATE,
format = "%d-%b-%y %H.%M.%OS %p"),
Date = as.Date(TRANSACTION_DATE),
time = format(TRANSACTION_DATE, "%T"))
Read ?strptime for all formatting options.
data
Using a reproducible example
df <- data.frame(col1 = 1:3, TRANSACTION_DATE = c("01-OCT-18 12.01.23.000000 AM",
"01-OCT-18 12.02.23.000000 AM", "01-OCT-18 12.03.23.000000 AM"))
df
# col1 TRANSACTION_DATE
#1 1 01-OCT-18 12.01.23.000000 AM
#2 2 01-OCT-18 12.02.23.000000 AM
#3 3 01-OCT-18 12.03.23.000000 AM
I would use the lubridate package:
library(lubridate)
library(dplyr)
df %>%
mutate(TRANSACTION_DATE = dmy_hms(TRANSACTION_DATE),
Date = date(TRANSACTION_DATE),
time = format(TRANSACTION_DATE, "%T"))

Convert hour to date-time

I have a data frame with hour stamp and corresponding temperature measured. The measurements are taken at random intervals over time continuously. I would like to convert the hours to respective date-time and temperature measured. My data frame looks like this: (The measurement started at 20/05/2016)
Time, Temp
09.25,28
10.35,28.2
18.25,29
23.50,30
01.10,31
12.00,36
02.00,25
I would like to create a data.frame with respective date-time and Temp like below:
Time, Temp
2016-05-20 09:25,28
2016-05-20 10:35,28.2
2016-05-20 18:25,29
2016-05-20 23:50,30
2016-05-21 01:10,31
2016-05-21 12:00,36
2016-05-22 02:00,25
I am thankful for any comments and tips on the packages or functions in R, I can have a look to do this. Thanks for your time.
A possible solution in base R:
df$Time <- as.POSIXct(strptime(paste('2016-05-20', sprintf('%05.2f',df$Time)), format = '%Y-%m-%d %H.%M', tz = 'GMT'))
df$Time <- df$Time + cumsum(c(0,diff(df$Time)) < 0) * 86400 # 86400 = 60 * 60 * 24
which gives:
> df
Time Temp
1 2016-05-20 09:25:00 28.0
2 2016-05-20 10:35:00 28.2
3 2016-05-20 18:25:00 29.0
4 2016-05-20 23:50:00 30.0
5 2016-05-21 01:10:00 31.0
6 2016-05-21 12:00:00 36.0
7 2016-05-22 02:00:00 25.0
An alternative with data.table (off course you can also use cumsum with diff instead of rleid & shift):
setDT(df)[, Time := as.POSIXct(strptime(paste('2016-05-20', sprintf('%05.2f',Time)), format = '%Y-%m-%d %H.%M', tz = 'GMT')) +
(rleid(Time < shift(Time, fill = Time[1]))-1) * 86400]
Or with dplyr:
library(dplyr)
df %>%
mutate(Time = as.POSIXct(strptime(paste('2016-05-20',
sprintf('%05.2f',Time)),
format = '%Y-%m-%d %H.%M', tz = 'GMT')) +
cumsum(c(0,diff(Time)) < 0)*86400)
which will both give the same result.
Used data:
df <- read.table(text='Time, Temp
09.25,28
10.35,28.2
18.25,29
23.50,30
01.10,31
12.00,36
02.00,25', header=TRUE, sep=',')
You can use a custom date format combined with some code that detects when a new day begins (assuming the first measurement takes place earlier in the day than the last measurement of the previous day).
# starting day
start_date = "2016-05-20"
values=read.csv('values.txt', colClasses=c("character",NA))
last=c(0,values$Time[1:nrow(values)-1])
day=cumsum(values$Time<last)
Time = strptime(paste(start_date,values$Time), "%Y-%m-%d %H.%M")
Time = Time + day*86400
values$Time = Time

Resources