表 reg_data
是一个 PostgreSQL 表。事实证明,在 PostgreSQL 中运行回归速度更快。但是,当我为 100,000 个数据集运行它时,我想一个数据集一个数据集地执行它,并将每个数据集的结果附加到一个表中。
有没有办法使用 native dplyr
动词将 PostgreSQL 数据附加到 PostgreSQL 表?我不确定将数据带到 R 然后将它们发送回 PostgreSQL 是否会产生巨大的成本(它只是 6 个数字和几个标识字段),但它看起来确实不雅观。
library(dplyr)
pg <- src_postgres()
reg_data <- tbl(pg, "reg_data")
reg_results <-
reg_data %>%
summarize(r_squared=regr_r2(y, x),
num_obs=regr_count(y, x),
constant=regr_intercept(y, x),
slope=regr_slope(y, x),
mean_analyst_fog=regr_avgx(y, x),
mean_manager_fog=regr_avgy(y, x)) %>%
collect() %>%
as.data.frame()
# Push to database.
dbWriteTable(pg$con, c("bgt", "within_call_data"), reg_results,
append=TRUE, row.names=FALSE)
最佳答案
dplyr
不包含在数据库中插入或更新记录的命令,因此没有完整的原生 dplyr
解决方案。但是您可以将 dplyr 与常规 SQL 语句结合使用,以避免将数据带到 R。
让我们从在 collect()
语句之前重现您的步骤开始
library(dplyr)
pg <- src_postgres()
reg_data <- tbl(pg, "reg_data")
reg_results <-
reg_data %>%
summarize(r_squared=regr_r2(y, x),
num_obs=regr_count(y, x),
constant=regr_intercept(y, x),
slope=regr_slope(y, x),
mean_analyst_fog=regr_avgx(y, x),
mean_manager_fog=regr_avgy(y, x))
现在,您可以使用 compute()
而不是 collect()
在数据库中创建临时表。
temp.table.name <- paste0(sample(letters, 10, replace = TRUE), collapse = "")
reg_results <- reg_results %>% compute(name=temp.table.name)
其中 temp.table.name
是一个随机表名。在计算中使用选项 name = temp.table.name
我们将这个随机名称分配给创建的临时表。
现在,我们将使用库 RPostgreSQL
创建一个使用存储在临时表中的结果的插入查询。由于临时表只存在于 src_postgresql()
创建的连接中,我们需要重用它。
library(RPostgreSQL)
copyconn <- pg$con
class(copyconn) <- "PostgreSQLConnection" # I get an error if I don't fix the class
最后插入查询
sql <- paste0("INSERT INTO destination_table SELECT * FROM ", temp.tbl.name,";")
dbSendQuery(copyconn, sql)
所以,一切都发生在数据库中,数据没有进入 R。
编辑
当我们从 reg_results
获取 temp.tbl.name
时,这篇文章的先前版本确实破坏了封装。在计算中使用选项 name=
可以避免这种情况。
关于r - 如何在没有 `dplyr` 的情况下将数据附加到 `collect()` 的 PostgreSQL 表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38592195/