假设我有一个命名向量,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
. 同样,对于 and 之间的时间段"2001-09-01"
,"2007-11-04"
我应该得到2
and 1
。
这个问题已经通过从zoo包扩展功能的xts包得到了很好的解决。
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
类型,或者最好是一个扩展包,可以有效地索引数百万个日期。
您需要将日期从字符转换为Date
类型as.Date()
(如果您有更多信息,例如一天中的时间,则为 POSIX 类型)。然后,您可以与标准的关系运算符(例如 <= 和 >=)进行比较。
您应该考虑使用诸如此类的时间序列包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
(或xts
、timeSeries
、fts
等)执行此操作的方法:
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[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