Want Only the Time Portion of a Date-Time Object in R

Want only the time portion of a date-time object in R

Once you use strptime you will of necessity get a date-time object and the default behavior for no date in the format string is to assume today's date. If you don't like that you will need to prepend a string that is the date of your choice.

@James' suggestion is equivalent to what I was going to suggest:

format(all_symbol$Time[j], format="%H:%M:%S")

The only package I know of that has time classes (i.e time of day with no associated date value) is package:chron. However I find that using format as a way to output character values from POSIXt objects lends itself well to functions that require factor input.

In the decade since this was written there is now a package named “hms” that has some sort of facility for hours, minutes, and seconds.

hms: Pretty Time of Day

Implements an S3 class for storing and formatting time-of-day values, based on the 'difftime' class.

How to use only time part of datetime in rstudio

Here is a solution, this uses dplyr::case_when with a custom function using lubridate functions. Hope this helps!

library(dplyr)

# Creating the function to filter with
hour_min <- function(x) lubridate::hour(x) + lubridate::minute(x)/60

mydata %>%
mutate(day.night = case_when(hour_min(start) > 8 & hour_min(start) <= 20 & hour_min(end) > 8 & hour_min(end) <= 20 ~ "day",
(hour_min(start) <= 8 | hour_min(start) > 20) & (hour_min(end) <= 8 | hour_min(end) > 20) ~ "night",
TRUE ~ "mixed"))

id start end day.night
1 m1 2020-01-03 10:00:00 2020-01-03 16:00:00 day
2 m1 2020-01-03 16:00:00 2020-01-03 19:20:00 day
3 m1 2020-01-03 19:20:00 2020-01-03 20:50:00 mixed
4 m2 2020-01-05 10:00:00 2020-01-05 15:20:00 day
5 m2 2020-01-05 15:20:00 2020-01-05 20:50:00 mixed
6 m2 2020-01-05 20:50:00 2020-01-05 22:00:00 night
7 m3 2020-01-06 06:30:00 2020-01-06 07:40:00 night
8 m4 2020-01-08 06:30:00 2020-01-08 07:50:00 night
9 m4 2020-01-08 07:50:00 2020-01-08 08:55:00 mixed

Date time conversion and extract only time

If your data is

a <- "17:24:00"

b <- strptime(a, format = "%H:%M:%S")

you can use lubridate in order to have a result of class integer

library(lubridate)
hour(b)
minute(b)

# > hour(b)
# [1] 17
# > minute(b)
# [1] 24

# > class(minute(b))
# [1] "integer"

and you can combine them using

# character
paste(hour(b),minute(b), sep=":")

# numeric
hour(b) + minute(b)/60

for instance.

I would not advise to do that if you want to do any further operations on your data. However, it might be convenient to do that if you want to plot the results.

R: How to handle times without dates?

Use the "times" class found in the chron package:

library(chron)

Enter <- c("09:12", "17:01")
Enter <- times(paste0(Enter, ":00"))

Exit <- c("10:15", "18:11")
Exit <- times(paste0(Exit, ":00"))

Exit - Enter # durations

sum(Enter < "10:00:00") # no entering before 10am
mean(Enter < "10:00:00") # fraction entering before 10am

sum(Exit > "17:00:00") # no exiting after 5pm
mean(Exit > "17:00:00") # fraction exiting after 5pm

table(cut(hours(Enter), breaks = c(0, 10, 17, 24))) # Counts for indicated hours
## (0,10] (10,17] (17,24]
## 1 1 0

table(hours(Enter)) # Counts of entries each hour
## 9 17
## 1 1

stem(hours(Enter), scale = 2)
## The decimal point is at the |

## 9 | 0
## 10 |
## 11 |
## 12 |
## 13 |
## 14 |
## 15 |
## 16 |
## 17 | 0

Graphics:

tab <- c(table(Enter), -table(Exit))  # Freq at each time.  Enter is pos; Exit is neg.
plot(times(names(tab)), tab, type = "h", xlab = "Time", ylab = "Freq")
abline(v = c(10, 17)/24, col = "red", lty = 2) # vertical red lines
abline(h = 0) # X axis

screenshot

How do I extract only the time parameters from Datetime variable in R?

There are a number of options to extract the 'time' part. Some are listed below:

 format(as.POSIXct(str1), '%H:%M:%S')
[1] "20:00:00"

Or

 sub('[^ ]+ ', '', str1)
#[1] "20:00:00"

Or

 strftime(str1, format='%H:%M:%S')
#[1] "20:00:00"

Or

 library(lubridate)
format(ymd_hms(str1), '%H:%M:%S')
#[1] "20:00:00"

The ggplot code can be changed to

 library(ggplot2)
ggplot(rtt, aes(x= factor(strftime(Var1, format='%H:%M:%S')),
y= Freq, colour=Var2, group=Var2)) +
xlab("R Vs T") +
geom_point() +
scale_x_discrete(labels = function(x) str_wrap(x, width = 2)) +
ggtitle("Number of T Vs R - through the day") +
theme(plot.title=element_text(size=rel(1.2), lineheight = 1 ))

Update

If you need to extract only the 'hour' part

 library(lubridate)
hour(ymd_hms(str1))
#[1] 20

data

 str1 <- '2015-03-23 20:00:00'

rtt <- structure(list(Var1 = c("2015-03-24 00:00:00",
"2015-03-24 01:00:00",
"2015-03-24 06:00:00", "2015-03-24 07:00:00", "2015-03-24 08:00:00",
"2015-03-24 09:00:00"), Var2 = c("RT", "RT", "RT", "RT", "RT",
"RT"), Freq = c(612L, 65L, 58L, 5132L, 4483L, 11112L)),
.Names = c("Var1", "Var2", "Freq"), class = "data.frame",
row.names = c(NA, -6L))

How do I plot only the time portion of a timestamp including a date?

How about this approach?

require("ggplot2")
dtstring <- c(
"2011-09-28 03:33:00", "2011-08-24 13:41:00", "2011-09-19 16:14:00",
"2011-08-18 11:01:00", "2011-09-17 06:35:00", "2011-08-15 12:48:00"
)
dtPOSIXct <- as.POSIXct(dtstring)

# extract time of 'date+time' (POSIXct) in hours as numeric
dtTime <- as.numeric(dtPOSIXct - trunc(dtPOSIXct, "days"))

p <- qplot(dtTime) + xlab("Time slot") + scale_x_datetime(format = "%S:00")
print(p)

The calculation, dtPOSIXct - trunc(dtPOSIXct, "days"), extracts time of POSIXct class objects in hours.

plot(p)

For ggplot2-0.9.1:

require("ggplot2")
require("scales")
dtstring <- c(
"2011-09-28 03:33:00", "2011-08-24 13:41:00", "2011-09-19 16:14:00",
"2011-08-18 11:01:00", "2011-09-17 06:35:00", "2011-08-15 12:48:00"
)
dtPOSIXct <- as.POSIXct(dtstring)

# extract time of 'date+time' (POSIXct) in hours as numeric
dtTime <- as.numeric(dtPOSIXct - trunc(dtPOSIXct, "days"))

p <- qplot(dtTime) + xlab("Time slot") +
scale_x_datetime(labels = date_format("%S:00"))
print(p)

For ggplot2-0.9.3.1:

require("ggplot2")
require("scales")
dtstring <- c(
"2011-09-28 03:33:00", "2011-08-24 13:41:00", "2011-09-19 16:14:00",
"2011-08-18 11:01:00", "2011-09-17 06:35:00", "2011-08-15 12:48:00"
)
dtPOSIXct <- as.POSIXct(dtstring)

# extract time of 'date+time' (POSIXct) in hours as numeric
dtTime <- as.numeric(dtPOSIXct - trunc(dtPOSIXct, "days"))
class(dtTime) <- "POSIXct"

p <- qplot(dtTime) + xlab("Time slot") +
scale_x_datetime(labels = date_format("%S:00"))
print(p)

How do I plot only the time portion of a timestamp including a date?

How about this approach?

require("ggplot2")
dtstring <- c(
"2011-09-28 03:33:00", "2011-08-24 13:41:00", "2011-09-19 16:14:00",
"2011-08-18 11:01:00", "2011-09-17 06:35:00", "2011-08-15 12:48:00"
)
dtPOSIXct <- as.POSIXct(dtstring)

# extract time of 'date+time' (POSIXct) in hours as numeric
dtTime <- as.numeric(dtPOSIXct - trunc(dtPOSIXct, "days"))

p <- qplot(dtTime) + xlab("Time slot") + scale_x_datetime(format = "%S:00")
print(p)

The calculation, dtPOSIXct - trunc(dtPOSIXct, "days"), extracts time of POSIXct class objects in hours.

plot(p)

For ggplot2-0.9.1:

require("ggplot2")
require("scales")
dtstring <- c(
"2011-09-28 03:33:00", "2011-08-24 13:41:00", "2011-09-19 16:14:00",
"2011-08-18 11:01:00", "2011-09-17 06:35:00", "2011-08-15 12:48:00"
)
dtPOSIXct <- as.POSIXct(dtstring)

# extract time of 'date+time' (POSIXct) in hours as numeric
dtTime <- as.numeric(dtPOSIXct - trunc(dtPOSIXct, "days"))

p <- qplot(dtTime) + xlab("Time slot") +
scale_x_datetime(labels = date_format("%S:00"))
print(p)

For ggplot2-0.9.3.1:

require("ggplot2")
require("scales")
dtstring <- c(
"2011-09-28 03:33:00", "2011-08-24 13:41:00", "2011-09-19 16:14:00",
"2011-08-18 11:01:00", "2011-09-17 06:35:00", "2011-08-15 12:48:00"
)
dtPOSIXct <- as.POSIXct(dtstring)

# extract time of 'date+time' (POSIXct) in hours as numeric
dtTime <- as.numeric(dtPOSIXct - trunc(dtPOSIXct, "days"))
class(dtTime) <- "POSIXct"

p <- qplot(dtTime) + xlab("Time slot") +
scale_x_datetime(labels = date_format("%S:00"))
print(p)

Automatically convert formats of of date-time data to date only in r

How about this:

library(tidyverse)
library(lubridate)

``` r
library(tidyverse)
library(lubridate)

df %>%
mutate(time_temp = dmy_hms(time, quiet = TRUE)) %>%
mutate(time = if_else(is.na(time_temp),
dmy_hm(time, quiet = TRUE),
time_temp)) %>%
select(-time_temp)
#> # A tibble: 4 x 1
#> time
#> <dttm>
#> 1 2020-01-01 00:00:01
#> 2 2020-01-02 00:01:01
#> 3 2020-01-04 00:02:00
#> 4 2020-01-03 01:02:00

reprex data

df <- tibble(
time = c("01/01/2020 00:00:01", "02/01/2020 00:01:01", "04/01/20 00:02", "03/01/20 01:02")
)

Controlling how a date-time object is printed without coercing to a character?

It's pretty annoying that the base R functions for writing data don't have an argument to let the user easily adjust the datetime format.

There are ways around it, though. Here's what I've done sometimes when I want to specify a format quickly and I don't need to worry about side effects:

# In bash
Rscript -e "x <- readRDS('foo.rds'); "\
-e "as.character.POSIXct <- function(x) format(x, format='%Y-%m-%d %H:%M:%S%z'); " \
-e "write.csv(x, 'foo.csv', row.names=FALSE)"

(I'm showing that in a shell command just to emphasize that you'll want the new as.character.POSIXct method to disappear after using it.)

The essence is overriding the as.character method for the POSIXct class (for arcane reasons, overriding for the parent POSIXt class won't work):

as.character.POSIXct <- function(x)
format(x, format='%Y-%m-%d %H:%M:%S%z')

It's not something that should be done in a larger codebase where the global effects might spill into code that's not expecting it, though!

Storing time without date but not as class character

The chron package has a "times" class that might be helpful for you. Starting with something similar to what you have so far:

x <- c("1:30 AM", "6:29 AM", "6:59 AM", "9:54 AM", "10:14 AM", "3:15 PM"))
a <- as.POSIXct(x, tz = "", format = "%I:%M %p", usetz = FALSE)

Then we can use the times function with format

library(chron)
(tms <- times(format(a, "%H:%M:%S")))
# [1] 01:30:00 06:29:00 06:59:00 09:54:00 10:14:00 15:15:00
attributes(tms)
# $format
# [1] "h:m:s"
#
# $class
# [1] "times"


Related Topics



Leave a reply



Submit