I am wondering if I am missing something?!
I would like to know: is there a better/shorter way to get minutes from a datetime object:
Lessons studied so far:
Extract time (HMS) from lubridate date time object?
converting from hms to hour:minute in r, or rounding in minutes from hms
R: Convert hours:minutes:seconds
My tibble:
df <- structure(list(dttm = structure(c(-2209068000, -2209069200, -2209061520,
-2209064100, -2209065240), tzone = "UTC", class = c("POSIXct",
"POSIXt"))), row.names = c(NA, -5L), class = c("tbl_df", "tbl",
"data.frame"))
# A tibble: 5 x 1
dttm
<dttm>
1 1899-12-31 02:00:00
2 1899-12-31 01:40:00
3 1899-12-31 03:48:00
4 1899-12-31 03:05:00
5 1899-12-31 02:46:00
I would like to add a new column with minutes as integer:
My approach so far:
library(dplyr)
library(lubridate) # ymd_hms
library(hms) # as_hms
library(chron) # times
test %>%
mutate(dttm_min = as_hms(ymd_hms(dttm)),
dttm_min = 60*24*as.numeric(times(dttm_min)))
# A tibble: 5 x 2
dttm dttm_min
<dttm> <dbl>
1 1899-12-31 02:00:00 120
2 1899-12-31 01:40:00 100
3 1899-12-31 03:48:00 228
4 1899-12-31 03:05:00 185
5 1899-12-31 02:46:00 166
This gives me the result I want, but I need for this operation 3 packages. Is there a more direct way?
CodePudding user response:
Here is a base R way -
You can extract the time using format
, change the date to '1970-01-01'
(Since R datetime starts with '1970-01-01'
), convert to numeric and divide the time by 60 to get the duration in minutes.
as.numeric(as.POSIXct(paste('1970-01-01', format(df$dttm, '%T')), tz = 'UTC'))/60
#[1] 120 100 228 185 166
CodePudding user response:
Here are two ways.
Base R
with(df, as.integer(format(dttm, "%M")) 60*as.integer(format(dttm, "%H")))
#[1] 120 100 228 185 166
Another base R option, using class "POSIXlt"
as proposed here.
minute_of_day <- function(x){
y <- as.POSIXlt(x)
60*y$hour y$min
}
minute_of_day(df$dttm)
#[1] 120 100 228 185 166
Package lubridate
lubridate::minute(df$dttm) 60*lubridate::hour(df$dttm)
#[1] 120 100 228 185 166
If the package is loaded, this can be simplified, with the same output, to
library(lubridate)
minute(df$dttm) 60*hour(df$dttm)
CodePudding user response:
We can use
library(data.table)
as.numeric(as.ITime(format(df$dttm, '%T')))/60
[1] 120 100 228 185 166
CodePudding user response:
For sake of completeness, the time of day (in minutes) can be calculated by taking the difftime()
between the POSIXct datetime object and the beginning of the day, e.g.,
difftime(df$dttm, lubridate::floor_date(df$dttm, "day"), units = "min")
Time differences in mins
[1] 120 100 228 185 166
Besides base R only one other package is required.
According to help("difftime")
, difftime()
returns an object of class "difftime
" with an attribute indicating the units.