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
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.
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.
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
Combine Lists While Overriding Values with Same Name in R
Using R to Fit a Sigmoidal Curve
Why Are Lubridate Functions So Slow When Compared with As.Posixct
Adding Scale Bar to Ggplot Map
Using 'Fread' to Import CSV File from an Archive into 'R' Without Extracting to Disk
How to Summarizing Data Statistics Using R
Create All Possible Combiations of 0,1, or 2 "1"S of a Binary Vector of Length N
Align Edges of Ggplot Choropleth (Legend Title Varies)
Ggplot2 Multiline Title, Different Indentations
When Writing My Own R Package, I Can't Seem to Get Other Packages to Import Correctly
Using Get Inside Lapply, Inside a Function
How to Replace Numeric Codes with Value Labels from a Lookup Table
Export All User Inputs in a Shiny App to File and Load Them Later
Delete Rows Based on Multiple Conditions with Dplyr
Specifying the Scale for the Density in Ggplot2's Stat_Density2D