Выберите значения из вектора, используя дату как индекс

StackOverflow https://stackoverflow.com/questions/2736631

  •  02-10-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

Эта проблема была решена на благо мнение пакет, который расширяет функциональность от зоопарк упаковка.

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, если у вас больше информации, как время суток). Тогда вы можете сделать сравнения со стандартом реляционные операторы такие как <= и> =.

Вы должны рассмотреть возможность использования пакета Thumeries, таких как 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, это не список, он называется вектор).

Как штаты Дирка в своем ответе, лучше использовать 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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top