Выберите значения из вектора, используя дату в качестве индекса - PullRequest
1 голос
/ 29 апреля 2010

Предположим, у меня есть именованный вектор, 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" я должен получить 2 и 1.

Ответы [ 3 ]

4 голосов
/ 29 апреля 2010

Эта проблема была решена навсегда с помощью пакета 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 голосов
/ 29 апреля 2010

Вам необходимо преобразовать даты из символов в тип 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 виньетка для получения дополнительной информации.

1 голос
/ 29 апреля 2010

Используя тот факт, что даты в лексическом порядке:

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, это не список, он назван вектором).

Как Дирк заявляет в своем ответе, лучше использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...