【问题标题】:How do I get all the dates with a particular time from a zoo object?如何从动物园对象中获取特定时间的所有日期?
【发布时间】:2020-03-17 15:25:41
【问题描述】:

假设我有一个日期/时间 (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
...

这应该很简单,但我想不出如何获取所有日期/时间的列表,假设时间是上午 10:10:00 ...


动物园数据对象示例:

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 实现,但其他包会很有趣

【问题讨论】:

    标签: r dataframe zoo


    【解决方案1】:

    一种方法是使用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))]
    )
    

    【讨论】:

    • 我不想解析出时间字符串,而是说“给我时间为 10:10:00 的所有行”
    • 哇,太好了!
    • lubridate 代码假定数据中的秒数始终为 0,而 grep 代码则不然。
    【解决方案2】:

    我们可以使用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 
    

    【讨论】:

      【解决方案3】:

      像这样使用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")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-08
        • 2013-02-13
        • 2012-06-24
        • 1970-01-01
        • 1970-01-01
        • 2013-05-15
        • 1970-01-01
        相关资源
        最近更新 更多