R: Как отфильтровать/подмножить последовательность дат

У меня есть эти данные: (завершено за декабрь)

      date     sessions
1   2014-12-01  1932
2   2014-12-02  1828
3   2014-12-03  2349
4   2014-12-04  8192
5   2014-12-05  3188
6   2014-12-06  3277

И необходимо подмножить/отфильтровать это, например, с 2014-12-05 до 2014-12-25.

Я знаю, что вы можете создать последовательность с помощью оператора :.

Пример: б ‹- с(1:5)

Но как отфильтровать последовательность? я пробовал это

NewDate <- filter(Dates, date("2014-12-05":"2014-12-12"))

Но говорит:

Ошибка: неожиданный символ в: NewDate ‹- filter(Dates, date(2014-12-05:2014-12-12) NewDate


person Omar Gonzales    schedule 05.02.2015    source источник


Ответы (4)


вы могли бы использовать subset

Создание образцов данных:

temp<-
read.table(text="date     sessions
2014-12-01  1932
2014-12-02  1828
2014-12-03  2349
2014-12-04  8192
2014-12-05  3188
2014-12-06  3277", header=T)

Убедитесь, что он в формате даты:

temp$date <- as.Date(temp$date, format= "%Y-%m-%d")

temp



 #        date sessions
 # 1 2014-12-01     1932
 # 2 2014-12-02     1828
 # 3 2014-12-03     2349
 # 4 2014-12-04     8192
 # 5 2014-12-05     3188
 # 6 2014-12-06     3277

Использование subset :

subset(temp, date> "2014-12-03" & date < "2014-12-05")

который дает:

  #        date sessions
  # 4 2014-12-04     8192

вы также можете использовать []:

temp[(temp$date> "2014-12-03" & temp$date < "2014-12-05"),]
person jalapic    schedule 05.02.2015
comment
Это было так просто, спасибо! Я думаю, что я так устал, что просто делаю вещи сложнее в своей голове, чем они есть на самом деле... - person Omar Gonzales; 05.02.2015

Если вы хотите использовать dplyr, вы можете попробовать что-то вроде этого.

mydf <- structure(list(date = structure(c(16405, 16406, 16407, 16408, 
16409, 16410), class = "Date"), sessions = c(1932L, 1828L, 2349L, 
8192L, 3188L, 3277L)), .Names = c("date", "sessions"), row.names = c("1", 
"2", "3", "4", "5", "6"), class = "data.frame")

# Create date object
mydf$date <- as.Date(mydf$date) 

filter(mydf, between(date, as.Date("2014-12-02"), as.Date("2014-12-05")))

#If you avoid using `between()`, the code is simpler.

filter(mydf, date >= "2014-12-02", date <= "2014-12-05")
filter(mydf, date >= "2014-12-02" & date <= "2014-12-05")

#        date sessions
#1 2014-12-02     1828
#2 2014-12-03     2349
#3 2014-12-04     8192
#4 2014-12-05     3188
person jazzurro    schedule 05.02.2015
comment
Я думал, что логичным условием будет &, но похоже, что , работает. Это что-то новое для меня. Спасибо. - person akrun; 05.02.2015
comment
@akrun Кажется, здесь оба в порядке, не так ли? Я видел обе версии в учебнике Хэдли по dplyr в формате pdf от UseR! 2014. Выложу обе версии. Я немного озадачен поведением between. Интересно, почему нужно снова использовать as.Date. - person jazzurro; 05.02.2015
comment
Это требуется по той же причине, что и seq.Date(as.Date(x1),as.Date(x2),by="years") — вам нужно работать с объектом Date, чтобы данные совпадали. - person thelatemail; 05.02.2015
comment
@thelatemail Этот пример прояснил мой разум. Большое спасибо. :) - person jazzurro; 05.02.2015
comment
@akrun Как всегда приятно. Кажется, что between в data.table экономит набор текста. - person jazzurro; 05.02.2015

Вариант с использованием data.table

 library(data.table)
 setDT(df)[date %between% c('2014-12-02', '2014-12-05')]
 #         date sessions
 #1: 2014-12-02     1828
 #2: 2014-12-03     2349
 #3: 2014-12-04     8192
 #4: 2014-12-05     3188

Это должно работать, даже если дата является символьным столбцом

 df$date <- as.character(df$date)
 setDT(df)[date %between% c('2014-12-02', '2014-12-05')]
 #       date sessions
 #1: 2014-12-02     1828
 #2: 2014-12-03     2349
 #3: 2014-12-04     8192
 #4: 2014-12-05     3188

В случае, если мы хотим подмножество, исключая диапазон

  setDT(df)[between(date, '2014-12-02', '2014-12-05', incbounds=FALSE)]
  #         date sessions
  #1:  2014-12-03     2349
  #2:  2014-12-04     8192

данные

 df <-  structure(list(date = structure(c(16405, 16406, 16407, 16408, 
 16409, 16410), class = "Date"), sessions = c(1932L, 1828L, 2349L, 
 8192L, 3188L, 3277L)), .Names = c("date", "sessions"), row.names = c("1", 
 "2", "3", "4", "5", "6"), class = "data.frame")
person akrun    schedule 05.02.2015
comment
Я искал самый быстрый вариант фильтрации даты для использования внутри ggplot::geom_xxxx(data=DT[]). Быстрое исследование показывает, что это будет самый быстрый вариант: имеет ли значение с точки зрения производительности использование %between% или between()? Использует ли он as.Date() во внутренних компонентах? Что я делаю: 'ggplot(DT, aes(date, y_var)) + geom_step() + geom_step(data = DT[,DATE %in% ymd(2017-02-01):ymd(2017-10-31 ),] , aes(date, yvar), col='black', size=1.6 )' Это просто для выделения строки текущего (2017) года: черный и размер больше. - person Dan; 18.08.2017
comment
@Dan Если вы используете between из data.table, то есть between(x, lower, upper, incbounds=TRUE)# x %between% y - person akrun; 18.08.2017
comment
Преобразует ли %between% символ даты в настоящую дату? В чем разница между использованием %between% data.table и %within% lubridate? - person skan; 14.02.2021

С lubridate,

mydates <- interval(start = "2014-12-05", end = "2014-12-25")
NewDate <- Dates[which(date %within% mydates),]
person dez93_2000    schedule 13.12.2019
comment
Вам не нужно which. - person hmhensen; 14.12.2019
comment
Не согласен. Which индексирует строки, соответствующие условию, и возвращает их подмножество. В противном случае индекс подмножества является вектором TRUE/FALSE, но строки NA не будут ни T, ни F и, таким образом, вернут в результат все строки NA. - person dez93_2000; 14.12.2019
comment
Ты прав. Интересно. Я думал, что подмножество будет возвращать только TRUE, а не просто не возвращать FALSE (поскольку NA также является логическим). Думаю, я слишком много использовал dplyr. Использование его в filter не возвращает NA. Спасибо. - person hmhensen; 14.12.2019