【问题标题】:Select values from vector using Date as index使用日期作为索引从向量中选择值
【发布时间】:2011-02-13 18:20:26
【问题描述】:

假设我有一个命名向量,bar:

bar=c()
bar["1997-10-14"]=1
bar["2001-10-14"]=2
bar["2007-10-14"]=1

如何从bar 中选择索引在特定日期范围内的所有值?所以,如果我查找"1995-01-01""2000-06-01" 之间的所有值,我应该得到1。同样,对于"2001-09-01""2007-11-04" 之间的时间段,我应该得到21

【问题讨论】:

  • 仅供参考:您正在创建一个命名的数字向量,而不是一个列表。

标签: r xts


【解决方案1】:

这个问题已经通过xts 包得到了很好的解决,它扩展了zoo 包的功能。

R> library(xts)
Loading required package: zoo
R> bar <- xts(1:3, order.by=as.Date("2001-01-01")+365*0:2)
R> bar
           [,1]
2001-01-01    1
2002-01-01    2
2003-01-01    3
R> bar["2002::"]        ## open range with a start year
           [,1]
2002-01-01    2
2003-01-01    3
R> bar["::2002"]        ## or end year
           [,1]
2001-01-01    1
2002-01-01    2
R> bar["2002-01-01"]    ## or hits a particular date
           [,1]
2002-01-01    2
R> 

这里还有很多——但基本的一点是对伪装成日期的字符串进行操作。

使用Date 类型,或者最好是为有效索引数百万个日期而构建的扩展包。

【讨论】:

    【解决方案2】:

    您需要使用 as.Date() 将日期从字符转换为 Date 类型(如果您有更多信息,例如一天中的时间,则为 POSIX 类型)。然后您可以与标准relational operators 进行比较,例如=。

    您应该考虑为此使用时间序列包,例如 zoo

    编辑

    只是为了回应您的评论,以下是使用现有向量的日期示例:

    > as.Date(names(bar)) < as.Date("2001-10-14")
    [1]  TRUE FALSE FALSE
    > bar[as.Date(names(bar)) < as.Date("2001-10-14")]
    1997-10-14 
             1
    

    虽然你真的应该只使用时间序列包。以下是使用zoo(或xtstimeSeriesfts 等)的方法:

    library(zoo)
    ts <- zoo(c(1, 2, 1), as.Date(c("1997-10-14", "2001-10-14", "2007-10-14")))
    ts[index(ts) < as.Date("2001-10-14"),]
    

    由于索引现在是Date 类型,因此您可以进行任意数量的比较。阅读zoo 小插图了解更多信息。

    【讨论】:

    • 嗯,我可能做错了,但如果我做类似 bar[as.Date("2001-10-14")] 的事情,我会得到涉及很多 NA 的非常奇怪的结果
    【解决方案3】:

    使用日期按词汇顺序的事实:

    bar[names(bar) > "1995-01-01" & names(bar) < "2000-06-01"]
    # 1997-10-14 
    #          1 
    
    bar[names(bar) > "2001-09-01" & names(bar) < "2007-11-04"]
    # 2001-10-14 2007-10-14 
    #          2          1 
    

    结果被命名为向量(正如你原来的bar,它不是一个列表它被命名为向量)。

    正如 Dirk 在他的回答中所说,出于效率原因,最好使用 Date。如果没有外部包,您可以重新排列数据并创建两个向量(或两列 data.frame),一个用于日期,一个用于值:

    bar_dates <- as.Date(c("1997-10-14", "2001-10-14", "2007-10-14"))
    bar_values <- c(1,2,1)
    

    然后使用简单的索引:

    bar_values[bar_dates > as.Date("1995-01-01") & bar_dates < as.Date("2000-06-01")]
    # [1] 1
    
    bar_values[bar_dates > as.Date("2001-09-01") & bar_dates < as.Date("2007-11-04")]
    # [1] 2 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 1970-01-01
      • 2021-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多