我正在尝试使用 Rpostgresql 将成功的 R 代码转换为 PL/R 代码,以避免将数据推入和拉出 postgreql 数据库。
代码是 data.table 上的 dcast:
#libs
library(RPostgreSQL);
library(data.table);
# connect
drv <- dbDriver("PostgreSQL");
con <- dbConnect(drv, dbname="postgres", user="postgres");
# load
cli_ranges <- dbGetQuery(con, "SELECT custid, prod_ranges, is_cli from cli_ranges;")
# DT
setDT(cli_ranges )
setkeyv(cli_ranges , c("prod_ranges"))
# pivot
cli_ranges.pivoted <- dcast(cli_ranges, custid ~ paste0("is_cli_", prod_ranges), fun=sum, value.var = "is_cli")
# send back to DB
dbWriteTable(con, "cli_ranges_pivoted", cli_ranges.pivoted, row.names=F)
R 中的代码运行良好且快速。
我现在正在尝试将代码推送到 PL/R 函数中,
CREATE OR REPLACE FUNCTION public.pivot()
RETURNS void AS
$BODY$
[copy/paste R code]
$BODY$
LANGUAGE plr;
...但是 R 代码的最后一行 ( dbWriteTable
) 抛出:
ERROR: R interpreter expression evaluation error
DETAIL: Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function 'dbWriteTable' for signature '"logical", "character", "data.frame"'
CONTEXT: In PL/R function pivot
将 data.table 更改为数据框 ( as.data.frame(cli_ranges.pivoted)
) 也不起作用。
一个技巧可能是返回 data.table/frame 以执行 aCREATE TABLE cli_ranges_pivoted AS SELECT pivot();
但我真的不知道如何将 data.frame 作为输出推送......
cli_ranges
桌子 :
custid prod_ranges is_cli
1 A 1
1 B 1
1 C 0
2 A 1
2 B 0
2 C 1
3 A 0
3 B 1
3 C 0
4 A 1
... ... ...
dcast(即旋转)后数据帧如下:
custid prod_ranges_A prod_ranges_B prod_ranges_C
1 1 1 0
2 1 0 1
3 0 1 0
4 1 ...
...
不同值的数量prod_ranges
经常变化,因此我可以提前定义旋转后的列数。
环境:Postgresql 9.5、R 3.3、PL/R 08.03.00.16、Win 10 64 位