从POSIXct中提取小时和秒,以便在R中打印

从POSIXct中提取小时和秒,以便在R中打印,r,datetime,ggplot2,lubridate,R,Datetime,Ggplot2,Lubridate,假设我有以下data.framefoo start.time duration 1 2012-02-06 15:47:00 1 2 2012-02-06 15:02:00 2 3 2012-02-22 10:08:00 3 4 2012-02-22 09:32:00 4 5 2012-03-21 13:47:00 5 和类(foo$start.time)返回 [1] "POSIXct" "POSIXt" 我想创建一个f

假设我有以下
data.frame
foo

           start.time duration
1 2012-02-06 15:47:00      1
2 2012-02-06 15:02:00      2
3 2012-02-22 10:08:00      3
4 2012-02-22 09:32:00      4
5 2012-03-21 13:47:00      5
类(foo$start.time)
返回

[1] "POSIXct" "POSIXt" 

我想创建一个
foo$duration
v的绘图<代码>foo$start.time。在我的场景中,我只对一天中的时间感兴趣,而不是一年中的实际日期。如何从向量的
POSIXct
类中将一天中的时间提取为小时:秒?

这是一个好问题,并突出了在R中处理日期的一些困难。lubridate包非常方便,因此下面我介绍了两种方法,一种使用base(如@RJ-)另一种使用lubridate

在原始post中重新创建数据帧(前两行):

foo <- data.frame(start.time = c("2012-02-06 15:47:00", 
                                 "2012-02-06 15:02:00",
                                 "2012-02-22 10:08:00"),
                  duration   = c(1,2,3))
然后选择上述方法之一将十进制小时分配给
foo$hr

foo$hr <- h.str

# If you prefer, the choice can be made at random:
foo$hr <- if(runif(1) > 0.5){ h.str } else { h.lub }

你可以信赖base R:

# Using R 2.14.2
# The same toy data
foo <- data.frame(start.time = c("2012-02-06 15:47:00", 
                                 "2012-02-06 15:02:00",
                                 "2012-02-22 10:08:00"),
                  duration   = c(1,2,3))
然后将其粘贴到任意日期以将其转换回POSIXct。在本例中,我使用2012年1月1日,但如果您没有指定日期,而是使用
格式
R,则使用当前日期

# Store time information as POSIXct, using an arbitrary date
foo$time <- as.POSIXct(paste("2012-01-01", substr(foo$start.time, 12, 16)))

这段代码比转换为字符串和返回数字要快得多

time <- c("1979-11-13T08:37:19-0500", "2014-05-13T08:37:19-0400");
time.posix <- as.POSIXct(time, format = "%Y-%m-%dT%H:%M:%S%z");
time.epoch <- as.vector(unclass(time.posix));
time.poslt <- as.POSIXlt(time.posix, tz = "America/New_York");
time.hour.new.york <- time.poslt$hour + time.poslt$min/60 + time.poslt$sec/3600;

> time;
[1] "1979-11-13T08:37:19-0500" "2014-05-13T08:37:19-0400"
> time.posix;
[1] "1979-11-13 15:37:19 IST" "2014-05-13 15:37:19 IDT"
> time.poslt;
[1] "1979-11-13 08:37:19 EST" "2014-05-13 08:37:19 EDT"
> time.epoch;
[1]  311348239 1399984639
> time.hour.new.york;
[1] 8.621944 8.621944
time.hour.new.york;
[1] 8.621944 8.621944

Lubridate不处理每天的时间数据,因此Hadley建议使用hms软件包处理此类数据。类似这样的方法会奏效:

library(lubridate)
foo <- data.frame(start.time = parse_datetime(c("2012-02-06 15:47:00", 
                                 "2012-02-06 15:02:00",
                                 "2012-02-22 10:08:00")),
                  duration   = c(1,2,3))


foo<-foo %>% mutate(time_of_day=hms::hms(second(start.time),minute(start.time),hour(start.time)))
库(lubridate)

foo这是一个古老的话题,但我发现关于这件事的问题和答案很少。我的解决方案如下

library(hms)
foo <- data.frame(start.time = c("2012-02-06 15:47:00", 
                             "2012-02-06 15:02:00",
                             "2012-02-22 10:08:00"),
              duration   = c(1,2,3))

foo$start.time = as.POSIXct( foo$start.time )

g1 = ggplot( ) + xlab("") + 
  geom_line( data = foo, aes(x = as.hms(start.time), y = duration ), color = "steelblue" )
g1

lubridate
zoo
可能对您有所帮助。但是在base R中,
格式(foo$start.time,format='%H:M')
。谢谢。
格式(foo$start.time,format='%H:M')
的一个问题是输出为字符格式。我希望输出是某种数字格式,这样就可以用作绘图的x轴。再一次,我会告诉你使用
lubridate
或者好的,使用
lubridate
软件包,我可以做
x取决于你的绘图方式,但是我引用的帖子应该会有所帮助。谢谢你的建议。但是,当绘制上述内容时,它将每个时间点视为标签或类别,而不是数字。换句话说,这些点在x轴上的间距相等。将差异与以下内容进行对比,取原始的
foo
,然后绘制以下
foo$start.time.numeric就问题而言,您在本文中描述的是,尝试
qplot(小时(foo$start.time)+分钟(foo$start.time)/60,foo$duration)+scale\x\u datetime(标签=日期格式(“%S:00”))
。看起来更改
scale\u x\u datetime
有一个
labels
参数。您可以使用
strtime
@RJ来剪切
lubridate
-我知道如何替换
lubridate::ymd\u hms
函数,但是我知道的唯一替换
lubridate::hour
lubridate::minute
的方法是
as.numeric(格式(foo$start.time),“%H”)
as.numeric(格式(foo$start.time),“%M”)
。所以我同意这是可以做到的(并且有理由减少依赖性),但是lubridate确实让它变得更容易。我将发布这两个选项,但欢迎您的建议。@David当我使用您的代码高于答案刻度时(labels=date\u格式(“%S:00”)。我收到一个错误,上面写着“error in f(…,self=self):断点和标签的长度不同”。您能告诉我一种绕过该错误的方法吗?fyi,as.hms已被弃用,并已被as\hms取代。
# Extract hour and minute as a character vector, of the form "%H:%M"
substr(foo$start.time, 12, 16)
# Store time information as POSIXct, using an arbitrary date
foo$time <- as.POSIXct(paste("2012-01-01", substr(foo$start.time, 12, 16)))
# Plot it using base graphics
plot(duration~time, data=foo)

# Plot it using ggplot2 (0.9.2.1)
library(ggplot2)
qplot(x=time, y=duration, data=foo)
time <- c("1979-11-13T08:37:19-0500", "2014-05-13T08:37:19-0400");
time.posix <- as.POSIXct(time, format = "%Y-%m-%dT%H:%M:%S%z");
time.epoch <- as.vector(unclass(time.posix));
time.poslt <- as.POSIXlt(time.posix, tz = "America/New_York");
time.hour.new.york <- time.poslt$hour + time.poslt$min/60 + time.poslt$sec/3600;

> time;
[1] "1979-11-13T08:37:19-0500" "2014-05-13T08:37:19-0400"
> time.posix;
[1] "1979-11-13 15:37:19 IST" "2014-05-13 15:37:19 IDT"
> time.poslt;
[1] "1979-11-13 08:37:19 EST" "2014-05-13 08:37:19 EDT"
> time.epoch;
[1]  311348239 1399984639
> time.hour.new.york;
[1] 8.621944 8.621944
library(lubridate)
foo <- data.frame(start.time = parse_datetime(c("2012-02-06 15:47:00", 
                                 "2012-02-06 15:02:00",
                                 "2012-02-22 10:08:00")),
                  duration   = c(1,2,3))


foo<-foo %>% mutate(time_of_day=hms::hms(second(start.time),minute(start.time),hour(start.time)))
library(hms)
foo <- data.frame(start.time = c("2012-02-06 15:47:00", 
                             "2012-02-06 15:02:00",
                             "2012-02-22 10:08:00"),
              duration   = c(1,2,3))

foo$start.time = as.POSIXct( foo$start.time )

g1 = ggplot( ) + xlab("") + 
  geom_line( data = foo, aes(x = as.hms(start.time), y = duration ), color = "steelblue" )
g1
time_breaks =    as.POSIXlt(c(
                   "2012-02-06 12:35:00 MSK", 
                   "2012-02-06 13:15:00 MSK",
                   "2012-02-06 14:22:00 MSK",
                   "2012-02-06 15:22:00 MSK"))
 g1 + 
  scale_x_time( breaks = as.hms( time_breaks ) ) +
  theme(  axis.text.x = element_text( angle=45, vjust=0.25) )