如何从动物园对象获取特定时间的所有日期?

How do I get all the dates with a particular time from a zoo object?

假设我有一个 date/times (POSIXct) 的动物园对象作为我的索引和值:

...                     val
2006-08-01 10:00:00      1
2006-08-01 10:10:00      2
2006-08-01 10:20:00      3
2006-08-01 10:30:00      4
...
2006-08-02 10:00:00      5
2006-08-02 10:10:00      6
2006-08-02 10:20:00      7
2006-08-02 10:30:00      8
...

这应该很简单,但我想不出如何获得所有 dates/times 的列表,假设时间是 10:10:00am ...


示例动物园数据对象:

Lines <- "datetime val
2006-08-01T10:00    1
2006-08-01T10:10    2
2006-08-01T10:20    3
2006-08-01T10:30    4
2006-08-01T10:40    10
2006-08-02T10:10    5
2006-08-02T10:20    6
2006-08-02T10:30    7
2006-08-02T10:40    8"

library(zoo)
z <- read.zoo(text = Lines, tz = "", header = TRUE, format = "%Y-%m-%dT%H:%M")

注意:我更喜欢 base-R/zoo 实现,但其他包会很有趣

一种方法是使用lubridate提取时间成分。这假设 second() 等于 0。

library(lubridate)

z[hour(index(z)) == 10 & minute(index(z)) == 10]

也可以强制转换为字符,然后搜索具体时间。

z[grep("10:10:00", index(z))]

出于好奇,我 运行 一个基准。结果估计是类型转换的结果,在小数据集上明显无意义。

不过,随着您添加更多条件,它会变慢。如果加上seconds(index(z)) == 0,那么lubridate的方法基本一样。 grep 解决方案可能是可行的方法。

library(microbenchmark)

benchmark <- microbenchmark(
  lubridate = z[hour(index(z)) == 10 & minute(index(z)) == 10],
  grep = z[grep("10:10:00", index(z))]
)

像这样使用grepgrepl。没有使用额外的包。

z[grepl("10:10:00", time(z))]
## 2006-08-01 10:10:00 2006-08-02 10:10:00 
##                   2                   6

另一种方法是使用 substrsubstring:

z[substring(time(z), 12, 20) == "10:10:00"])
## 2006-08-01 10:10:00 2006-08-02 10:10:00 
##                   2                   6

如果我们知道这些位置,那么另一种可能性是使用它们:

z[seq(2, length(z), 4)]
## 2006-08-01 10:10:00 2006-08-02 10:10:00 
##                   2                   6

备注

可复制形式的输入假设如下。 (好像下面的代码是复制到题中的。)

Lines <- "datetime        val
2006-08-01T10:00:00      1
2006-08-01T10:10:00      2
2006-08-01T10:20:00      3
2006-08-01T10:30:00      4
2006-08-02T10:00:00      5
2006-08-02T10:10:00      6
2006-08-02T10:20:00      7
2006-08-02T10:30:00      8"

library(zoo)
z <- read.zoo(text = Lines, header = TRUE, tz = "", format = "%Y-%m-%dT%T")

我们可以使用base::strftime:

z[strftime(z, format="%H:%M:%S") == strftime("1000-01-01 10:10:00", format="%H:%M:%S")]

 #> 2006-08-01 10:10:00 2006-08-02 10:10:00 
 #>                   2                   5