如何计算 dbplyr 中的月份差异(R 和 sql)
How to calculate difference in month in dbplyr (R and sql)
我尝试使用将我的代码发送到 sql 查询的 dbplyr 包来计算大型数据库的日期之间的月差。我尝试了类似问题中建议的不同方法,但它们没有用(例如下面的代码)。 Data2 是由 tbl()
创建的对象
Data2 %>% mutate(age_Months = (lubridate::interval(date_1, date_2)) / base::months(1))
#OR
library(lubridate)
Data2 %>% mutate(age_Months = TIMESTAMPDIFF(MONTH, date_1, date_2))
你有计算差异的想法吗?随意建议任何其他库和函数,没关系。我只需要月份的差异。谢谢
数据集如下
Data2 %>% select(date_1, date_2) %>% head() %>% collect()
# date_1 date_2
# <chr> <chr>
#1 2015-05-01 00:00:00.0 2036-02-01 00:00:00.0
#2 2015-05-01 00:00:00.0 2036-01-01 00:00:00.0
#3 2015-05-01 00:00:00.0 2031-03-01 00:00:00.0
#4 2015-05-01 00:00:00.0 2035-12-01 00:00:00.0
#5 2015-05-01 00:00:00.0 2035-05-01 00:00:00.0
#6 2015-05-01 00:00:00.0 2032-03-01 00:00:00.0
我通过 as.Date()
对它们进行了转换,但结果没有发生任何变化。
Data2 %>% mutate(date_1 = as.Date(date_1),
date_2 = as.Date(date_2))
# date_1 date_2
# <date> <date>
#1 2018-08-01 2036-02-01
#2 2018-08-01 2036-06-01
#3 2018-08-01 2036-01-01
#4 2018-08-01 2034-08-01
#5 2018-08-01 2033-08-01
#6 2018-08-01 2035-03-01
这里有两种可能的方法。
1) 使用 lubridate
dbplyr 翻译是为某些(但不是全部)lubridate 函数定义为某些(但不是全部)SQL 风格(上次我测试时)。所以我会先尝试以下操作:
Data2 %>%
mutate(year1 = lubridate::year(date_1),
year2 = lubridate::year(date_2),
month1 = lubridate::month(date_1),
month2 = lubridate::month(date_2)) %>%
mutate(age_months = 12*(year2 - year1) + month2 - month1) %>%
select(-year1, -year2, -month1, -month2)
2) 使用未翻译的 SQL 函数
Impala 包含一个 DATEDIFF
函数(文档 here)。当 dbplyr 遇到没有为其定义翻译的命令时,它会将未翻译的命令传递给数据库。
所以像下面这样:
Data2 %>%
mutate(age_months = DATEDIFF(date_2, date_1) / 30)
应该这样翻译成SQL:
SELECT *
,DATEDIFF(date_2, date_1) / 30 AS age_months
FROM data2
我尝试使用将我的代码发送到 sql 查询的 dbplyr 包来计算大型数据库的日期之间的月差。我尝试了类似问题中建议的不同方法,但它们没有用(例如下面的代码)。 Data2 是由 tbl()
Data2 %>% mutate(age_Months = (lubridate::interval(date_1, date_2)) / base::months(1))
#OR
library(lubridate)
Data2 %>% mutate(age_Months = TIMESTAMPDIFF(MONTH, date_1, date_2))
你有计算差异的想法吗?随意建议任何其他库和函数,没关系。我只需要月份的差异。谢谢
数据集如下
Data2 %>% select(date_1, date_2) %>% head() %>% collect()
# date_1 date_2
# <chr> <chr>
#1 2015-05-01 00:00:00.0 2036-02-01 00:00:00.0
#2 2015-05-01 00:00:00.0 2036-01-01 00:00:00.0
#3 2015-05-01 00:00:00.0 2031-03-01 00:00:00.0
#4 2015-05-01 00:00:00.0 2035-12-01 00:00:00.0
#5 2015-05-01 00:00:00.0 2035-05-01 00:00:00.0
#6 2015-05-01 00:00:00.0 2032-03-01 00:00:00.0
我通过 as.Date()
对它们进行了转换,但结果没有发生任何变化。
Data2 %>% mutate(date_1 = as.Date(date_1),
date_2 = as.Date(date_2))
# date_1 date_2
# <date> <date>
#1 2018-08-01 2036-02-01
#2 2018-08-01 2036-06-01
#3 2018-08-01 2036-01-01
#4 2018-08-01 2034-08-01
#5 2018-08-01 2033-08-01
#6 2018-08-01 2035-03-01
这里有两种可能的方法。
1) 使用 lubridate
dbplyr 翻译是为某些(但不是全部)lubridate 函数定义为某些(但不是全部)SQL 风格(上次我测试时)。所以我会先尝试以下操作:
Data2 %>%
mutate(year1 = lubridate::year(date_1),
year2 = lubridate::year(date_2),
month1 = lubridate::month(date_1),
month2 = lubridate::month(date_2)) %>%
mutate(age_months = 12*(year2 - year1) + month2 - month1) %>%
select(-year1, -year2, -month1, -month2)
2) 使用未翻译的 SQL 函数
Impala 包含一个 DATEDIFF
函数(文档 here)。当 dbplyr 遇到没有为其定义翻译的命令时,它会将未翻译的命令传递给数据库。
所以像下面这样:
Data2 %>%
mutate(age_months = DATEDIFF(date_2, date_1) / 30)
应该这样翻译成SQL:
SELECT *
,DATEDIFF(date_2, date_1) / 30 AS age_months
FROM data2