你是对的,lubridate 和 dbplyr 不能很好地协同工作(现在)。因此,我使用 sql 片段进行大部分 dbplyr 日期操作。
基于这个答案 and 这个网站,从日期中添加/减去时间的 postgresql 语法是:
SELECT old_date + INTERVAL '1 day' AS new_date;
基于此我会尝试以下操作:
output = base_data %>% mutate(lookback_date = date - sql("INTERVAL '1 year'"))
当我使用模拟连接执行此操作时,它会生成正确的语法:
library(dplyr)
library(dbplyr)
df = data.frame(my_num = c(1,2,3), my_dates = as.Date(c('2000-01-01','2000-02-02','2000-03-03')))
df = tbl_lazy(df, con = simulate_postgres())
output = df %>% mutate(new_date = my_dates - sql("INTERVAL '1 year'"))
show_query(output)
# <SQL>
# SELECT `my_num`, `my_dates`, `my_dates` - INTERVAL '1 year' AS `new_date`
# FROM `df`
UPDATE:根据评论,您首先要从日期时间转换为日期。
看来 dbplyr 确实支持翻译as.Date
到 PostgreSQL (as.Date
是基础 R 的一部分,而不是 lubridate 的一部分)。因此,您可以使用以下命令将列转换(转换)为日期:
library(dplyr)
library(dbplyr)
df = data.frame(my_str = c('2000-01-01','2000-02-02','2000-03-03'))
df = tbl_lazy(df, con = simulate_postgres())
output = df %>% mutate(my_date = as.Date(my_str))
show_query(output)
# <SQL>
# SELECT `my_str`, CAST(`my_str` AS DATE) AS `my_date`
# FROM `df`
PostgreSQL 似乎也不允许您添加一年的间隔。一种替代方法是从日期中提取年、月和日,在年份上加一,然后重新组合。
遵循这两个参考文献(Postgre 日期参考 and 日期部分函数) and this回答,你可能想要类似下面的东西:
output = df %>%
mutate(the_year = DATE_PART('year', my_date),
the_month = DATE_PART('month', my_date),
the_day = DATE_PART('day', my_date)) %>%
mutate(new_date = MAKE_DATE(the_year + 1, the_month, the_day)