从R中提取POSIXct中的小时和秒作为绘图目的
假设我有以下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
和class(foo$start.time)
返回
[1] "POSIXct" "POSIXt"
我想创build一个foo$duration
foo$start.time
。 在我的情况下,我只对一天的时间感兴趣,而不是一年中的实际一天。 如何从POSIXct
类的向量中提取小时:秒的时间?
这是一个很好的问题,并突出了在R中处理date的一些困难。lubridate包是非常方便的,所以下面我提出了两种方法,一种使用base(如@ RJ-所示),另一种使用lubridate。
重新创build原始文章中的数据框(的前两行):
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和POSIXt类(两种方法来做到这一点)
# using base::strptime t.str <- strptime(foo$start.time, "%Y-%m-%d %H:%M:%S") # using lubridate::ymd_hms library(lubridate) t.lub <- ymd_hms(foo$start.time)
现在,提取时间为十进制小时
# using base::format h.str <- as.numeric(format(t.str, "%H")) + as.numeric(format(t.str, "%M"))/60 # using lubridate::hour and lubridate::minute h.lub <- hour(t.lub) + minute(t.lub)/60
certificate这些方法是平等的:
identical(h.str, h.lub)
然后select上述方法之一来指定十进制小时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 }
然后使用ggplot2软件包进行绘图:
library(ggplot2) qplot(foo$hr, foo$duration) + scale_x_datetime(labels = "%S:00")
你可以依靠基地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以结构化方式包含date – 时间信息,因此可以依靠substr
来提取POSIXct向量内的时间位置上的字符。 也就是说,如果您知道POSIXct的格式(如何在打印时显示),则可以提取小时和分钟:
# Extract hour and minute as a character vector, of the form "%H:%M" substr(foo$start.time, 12, 16)
然后粘贴到任意date将其转换回POSIXct。 在示例中,我使用2012年1月1日,但如果不指定date,而是使用format
R使用当前date。
# Store time information as POSIXct, using an arbitrary date foo$time <- as.POSIXct(paste("2012-01-01", substr(foo$start.time, 12, 16)))
而且plot
和ggplot2
知道如何在POSIXct中格式化时间。
# 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)
此代码比转换为string并返回数字要快得多
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