I am trying to convert a successful R code using Rpostgresql into a PL/R code in order to avoid pushing/pulling data in and out of the postgreql database.
Code is a dcast on a data.table:
#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)
Code in R is working fine & fast.
I am now trying to push the code in a PL/R function,
CREATE OR REPLACE FUNCTION public.pivot()
RETURNS void AS
$BODY$
[copy/paste R code]
$BODY$
LANGUAGE plr;
... but the last line of the R code (dbWriteTable
) throws :
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
Changing the data.table to a dataframe (as.data.frame(cli_ranges.pivoted)
) is not working either.
One trick could be to return the data.table/frame in order to perform a CREATE TABLE cli_ranges_pivoted AS SELECT pivot();
but I don't really know how to push the data.frame as an output...
cli_ranges
table :
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
... ... ...
After dcast (i.e. pivoting) datafram is as follow:
custid prod_ranges_A prod_ranges_B prod_ranges_C
1 1 1 0
2 1 0 1
3 0 1 0
4 1 ...
...
Number of distinct values in prod_ranges
changes often, so I can define in advance the number of columns after pivoting.
Env : Postgresql 9.5, R 3.3, PL/R 08.03.00.16, Win 10 64bits