将 RpostgreSQL 与 sqldf 一起使用会使 R 崩溃
Using RpostgreSQL with sqldf crashes R
我正在使用 sqldf
来训练 SQL 中的一些 r 用户。在加载 sqldf
之前加载 RPostgreSQL
或 RH2
将更改 sqldf
使用的默认值 SQL。这适用于 h2,但每次我加载 RPostgreSQL
,R 都会在第一次尝试查询时崩溃。我想让 sqldf
与 RPostgreSQL
一起使用,以启用 SQLite
和 h2
.
中缺少的日期函数
# packages
library(tidyverse)
# library(RH2) # comment out this row or the next to determine default SQL for sqldf
library(RPostgreSQL)
library(sqldf)
输出确认“sqldf 将默认使用 PostgreSQL”
创建一些数据:
set.seed(42)
N <- 1e6
sales <- tibble(
buyer_id = 1:N/100,
sales_date = sample(seq(as.Date('2018/01/01'), as.Date('2021/01/01'), by="day"), N, replace = TRUE),
sales_amount = rpois(N, 200)
)
崩溃R:
sqldf("
select
max(sales_date)
from sales
")
"R 会话中止
R遇到致命错误
会话已终止
如果不使用 H2 的唯一原因是 date_trunc
那么这里有一些解决方法。
1) 宏 这是 t运行cation 到 year/quarter/month/week 开头的解决方法。这些函数充当扩展为 H2 接受的代码的宏。请务必在 sqldf 前加上 fn$ 前缀,并用反引号将它们括起来以启用替换。请注意,在每种情况下,参数都是一个字符串。将 verbose=TRUE
参数添加到 sqldf 以查看生成的代码。
library(RH2)
library(sqldf)
trunc_year <- function(x) sprintf("DATEADD(day, 1-day_of_year(%s), %s)", x, x)
trunc_qtr <- function(x) sprintf("DATEADD(month, 3*(quarter(%s)-1), %s)", x,
trunc_year(x))
trunc_month <- function(x) sprintf("DATEADD(day, 1-day_of_month(%s), %s)", x, x)
trunc_week <- function(x) sprintf("DATEADD(day, -iso_day_of_week(%s), %s)", x, x)
# test
DF <- data.frame(x = as.Date("2021-11-15"))
fn$sqldf("select x,
`trunc_year('x')` year,
`trunc_qtr('x')` qtr,
`trunc_month('x')` month,
`trunc_week('x')` week
from DF")
## x year qtr month week
## 1 2021-11-15 2021-01-01 2021-10-01 2021-11-01 2021-11-14
2) 修补 RH2 另一种可能性是用具有 date_trunc
的较新版本的 H2 修补你的 RH2 安装。为此,我们删除了 RH2 中包含 H2 的 h2-1.3.175.jar 文件,并将其替换为更新版本的 h2-1.4.200.jar。只要您在 RH2 安装的 java 子目录中具有写权限,这应该可以工作。只需 运行 R 中的这段代码,您的 RH2 安装就会被修补。
u <- "https://h2database.com/h2-2019-10-14.zip"
z <- basename(u)
tmp <- tempdir() # create temporary dir
old.dir <- setwd(tmp) # go to it
download.file(u, z) # download u
unzip(z, "h2/bin/h2-1.4.200.jar") # extract jar from zip file
# copy new jar file to RH2 installation and remove old one
new.jar <- file.path(tmp, "h2", "bin", "h2-1.4.200.jar")
old.jar <- dir(system.file("java", package = "RH2"), "h2.*jar$", full.names = TRUE)
if (basename(old.jar) != basename(new.jar)) {
file.copy(new.jar, dirname(old.jar))
file.remove(old.jar)
}
setwd(old.dir) # return to original directory
# test
library(RH2)
library(sqldf)
sqldf("select h2version()")
## '1.4.200'
## 1 1.4.200
# see more tests in (3) below
3) 重建 RH2 另一种可能性是使用具有 date_trunc
的较新版本的 H2 创建新的 RH2 源版本。第一个参数是 'year'、'quarter'、'month' 或 'week',第二个参数是日期。因此,如果您愿意用这个新的 H2 版本重建 RH2,那么它是可用的。
(a) 从https://cran.r-project.org/package=RH2下载RH2的源码并解压创建目录树RH2。
(b) 下载此 h2 zip https://h2database.com/h2-2019-10-14.zip 并从该 zip 文件中提取 h2/bin/h2-1.4.200.jar 并将 jar 文件放在 RH2/inst/java 目录中RH2 源删除旧的 h2-1.3.175.jar
(c) 像这样重建和测试 RH2:
# rebuild RH2
# cd to the RH2 directory containing its DESCRIPTION file
setwd("...whatever.../RH2")
# build RH2
# on Windows this needs Rtools40 (not an R package)
# https://cran.r-project.org/bin/windows/Rtools/
library(devtools)
build()
install(args = "--no-multiarch")
# test
library(RH2)
library(sqldf)
sqldf("select h2version()") # check it's the latest version
## '1.4.200'
## 1 1.4.200
DF <- data.frame(x = as.Date("2000-11-15"))
sqldf("select date_trunc('month', x) from DF")
## DATE_TRUNC('month', x)
## 1 2000-11-01
我正在使用 sqldf
来训练 SQL 中的一些 r 用户。在加载 sqldf
之前加载 RPostgreSQL
或 RH2
将更改 sqldf
使用的默认值 SQL。这适用于 h2,但每次我加载 RPostgreSQL
,R 都会在第一次尝试查询时崩溃。我想让 sqldf
与 RPostgreSQL
一起使用,以启用 SQLite
和 h2
.
# packages
library(tidyverse)
# library(RH2) # comment out this row or the next to determine default SQL for sqldf
library(RPostgreSQL)
library(sqldf)
输出确认“sqldf 将默认使用 PostgreSQL”
创建一些数据:
set.seed(42)
N <- 1e6
sales <- tibble(
buyer_id = 1:N/100,
sales_date = sample(seq(as.Date('2018/01/01'), as.Date('2021/01/01'), by="day"), N, replace = TRUE),
sales_amount = rpois(N, 200)
)
崩溃R:
sqldf("
select
max(sales_date)
from sales
")
"R 会话中止 R遇到致命错误 会话已终止
如果不使用 H2 的唯一原因是 date_trunc
那么这里有一些解决方法。
1) 宏 这是 t运行cation 到 year/quarter/month/week 开头的解决方法。这些函数充当扩展为 H2 接受的代码的宏。请务必在 sqldf 前加上 fn$ 前缀,并用反引号将它们括起来以启用替换。请注意,在每种情况下,参数都是一个字符串。将 verbose=TRUE
参数添加到 sqldf 以查看生成的代码。
library(RH2)
library(sqldf)
trunc_year <- function(x) sprintf("DATEADD(day, 1-day_of_year(%s), %s)", x, x)
trunc_qtr <- function(x) sprintf("DATEADD(month, 3*(quarter(%s)-1), %s)", x,
trunc_year(x))
trunc_month <- function(x) sprintf("DATEADD(day, 1-day_of_month(%s), %s)", x, x)
trunc_week <- function(x) sprintf("DATEADD(day, -iso_day_of_week(%s), %s)", x, x)
# test
DF <- data.frame(x = as.Date("2021-11-15"))
fn$sqldf("select x,
`trunc_year('x')` year,
`trunc_qtr('x')` qtr,
`trunc_month('x')` month,
`trunc_week('x')` week
from DF")
## x year qtr month week
## 1 2021-11-15 2021-01-01 2021-10-01 2021-11-01 2021-11-14
2) 修补 RH2 另一种可能性是用具有 date_trunc
的较新版本的 H2 修补你的 RH2 安装。为此,我们删除了 RH2 中包含 H2 的 h2-1.3.175.jar 文件,并将其替换为更新版本的 h2-1.4.200.jar。只要您在 RH2 安装的 java 子目录中具有写权限,这应该可以工作。只需 运行 R 中的这段代码,您的 RH2 安装就会被修补。
u <- "https://h2database.com/h2-2019-10-14.zip"
z <- basename(u)
tmp <- tempdir() # create temporary dir
old.dir <- setwd(tmp) # go to it
download.file(u, z) # download u
unzip(z, "h2/bin/h2-1.4.200.jar") # extract jar from zip file
# copy new jar file to RH2 installation and remove old one
new.jar <- file.path(tmp, "h2", "bin", "h2-1.4.200.jar")
old.jar <- dir(system.file("java", package = "RH2"), "h2.*jar$", full.names = TRUE)
if (basename(old.jar) != basename(new.jar)) {
file.copy(new.jar, dirname(old.jar))
file.remove(old.jar)
}
setwd(old.dir) # return to original directory
# test
library(RH2)
library(sqldf)
sqldf("select h2version()")
## '1.4.200'
## 1 1.4.200
# see more tests in (3) below
3) 重建 RH2 另一种可能性是使用具有 date_trunc
的较新版本的 H2 创建新的 RH2 源版本。第一个参数是 'year'、'quarter'、'month' 或 'week',第二个参数是日期。因此,如果您愿意用这个新的 H2 版本重建 RH2,那么它是可用的。
(a) 从https://cran.r-project.org/package=RH2下载RH2的源码并解压创建目录树RH2。
(b) 下载此 h2 zip https://h2database.com/h2-2019-10-14.zip 并从该 zip 文件中提取 h2/bin/h2-1.4.200.jar 并将 jar 文件放在 RH2/inst/java 目录中RH2 源删除旧的 h2-1.3.175.jar
(c) 像这样重建和测试 RH2:
# rebuild RH2
# cd to the RH2 directory containing its DESCRIPTION file
setwd("...whatever.../RH2")
# build RH2
# on Windows this needs Rtools40 (not an R package)
# https://cran.r-project.org/bin/windows/Rtools/
library(devtools)
build()
install(args = "--no-multiarch")
# test
library(RH2)
library(sqldf)
sqldf("select h2version()") # check it's the latest version
## '1.4.200'
## 1 1.4.200
DF <- data.frame(x = as.Date("2000-11-15"))
sqldf("select date_trunc('month', x) from DF")
## DATE_TRUNC('month', x)
## 1 2000-11-01