Фильтрация запросов из фрейма данных по части даты с использованием sqldf - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь извлечь и объединить 2 фрейма данных на основе некоторых частей даты, но это не работает. Фреймы данных следующие: -

startdf

startperiod
2015-10-01
2016-10-01
2017-10-01
2018-10-01


enddf

endperiod
2016-03-31
2017-03-31
2018-03-31

И startperiod, и endperiod имеют тип данных "Дата"

Это конечный результат, который я желаю: -

startperiod, endperiod
2015-10-01  2016-03-31
2016-10-01  2017-03-31
2017-10-01  2018-03-31
2018-10-01  Null

Эквивалентный SQL будет выглядеть примерно так: -

Select startperiod, endperiod
From startdf a lef join enddf b
On year(b.endperiod) = (year(a.startperiod) + 1)

есть ли способ сделать в R? Я считаю, что мне нужно использовать библиотеку sqldf и RH2, но я не смог ее запустить, что бы я ни делал.

Проще говоря, это должно работать, но не работает!

sqldf("Select * from startperioddf a where year(startperiod) = 2016")

Ответы [ 2 ]

0 голосов
/ 15 января 2019

1) RH2 Предположим,

  • данные приведены в воспроизводимой форме в примечании ниже. В частности, обратите внимание, что startdate и enddate предполагаются из класса Date.
  • опечатки в вопросе исправлены
  • использование базы данных h2 вместо sqlite по умолчанию

тогда ваш код работает:

library(sqldf)
library(RH2)

sql <- "Select startperiod, endperiod
  From startdf a left join enddf b
  On year(b.endperiod) = (year(a.startperiod) + 1)"
sqldf(sql)

дает:

  startperiod  endperiod
1  2015-10-01 2016-03-31
2  2016-10-01 2017-03-31
3  2017-10-01 2018-03-31
4  2018-10-01       <NA>

Также

sqldf("Select * from startdf a where year(startperiod) = 2016")

дает:

  startperiod
1  2016-10-01

Обязательно прочтите материал на сайте sqldf github: https://github.com/ggrothendieck/sqldf

2) sqlite Если вы хотите использовать SQL-сервер по умолчанию, тогда убедитесь, что RH2 НЕ загружен (в противном случае он будет предполагать, что вы хотите его использовать), и обратите внимание, что переменные класса Date будут загружены в sqlite в виде целых чисел, представляющих количество дней с начала эпохи Unix (поскольку в sqlite нет типа класса Date), поэтому нам нужно преобразовать дни с начала эпохи в годы (что можно сделать с помощью strftime, как показано).

sql2 <- "Select startperiod, endperiod
  From startdf a left join enddf b
  On strftime('%Y', b.endperiod * 3600 * 24, 'unixepoch') + 0 = 
     strftime('%Y', a.startperiod * 3600 * 24, 'unixepoch') + 1"
sqldf(sql2)

sqldf("Select * from startdf a 
  where strftime('%Y', a.startperiod * 3600 * 24, 'unixepoch') = '2016'")

Примечание

Lines1 <- "
startperiod
2015-10-01
2016-10-01
2017-10-01
2018-10-01"

Lines2 <- "
endperiod
2016-03-31
2017-03-31
2018-03-31"

startdf <- read.table(text = Lines1, header = TRUE, colClasses = "Date")
enddf <- read.table(text = Lines2, header = TRUE, colClasses = "Date")
0 голосов
/ 15 января 2019

Пакет sqldf в R по умолчанию использует ядро ​​базы данных SQLite. Следовательно, вы не можете использовать функцию year в своем запросе для извлечения части года из даты. Следующий запрос выполнит эту работу:

sqldf("Select * from startdf where strftime('%Y', startperiod) = '2016'")

Использует функцию SQLite strftime для сравнения определенных частей даты. Функция year определена в MySQL, поэтому вам, возможно, придется установить пакет RMySQL, а затем использовать аргумент drv = 'MySQL', чтобы указать механизм базы данных, который вы хотите использовать sqldf.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...