【问题标题】:call SQL function within R function在 R 函数中调用 SQL 函数
【发布时间】:2014-02-14 12:27:12
【问题描述】:

我想知道是否可以在 R 函数中调用 SQL 函数?

例如说我有这个虚拟数据和SQL函数写在Postgres 9.3

CREATE TABLE tbl (
   id VARCHAR(2) PRIMARY KEY
   ,name TEXT
   ,year_born NUMERIC
   ,nationality TEXT
);

INSERT INTO tbl(id, name, year_born, nationality)
VALUES ('A1','Bill',2001,'American')
      ,('B1','Anna',1997,'Swedish')
      ,('A2','Bill',1991,'American')
      ,('B2','Anna',2004,'Swedish')
      ,('B3','Anna',1989,'Swedish')
      ,('A3','Bill',1995,'American');


CREATE FUNCTION retrieve_data(TEXT) 
RETURNS TABLE ( id VARCHAR(2), name TEXT, year_born NUMERIC, nationality TEXT ) AS 
$func$
SELECT id, name, year_born, nationality
FROM tbl
WHERE name=$1 OR nationality=$1
GROUP BY 1
ORDER BY 1
$func$ LANGUAGE sql

我可以通过下面的RPostgreSQLsqldf 包访问这些数据并在R 环境中运行函数;

require(RPostgreSQL)
require(sqldf)

options(sqldf.RPostgreSQL.user = "****", 
        sqldf.RPostgreSQL.password = "****",
        sqldf.RPostgreSQL.dbname = "test_db",
        sqldf.RPostgreSQL.host = "localhost", 
        sqldf.RPostgreSQL.port = 5432)

sqldf("select * from retrieve_data('Bill')")

但是有没有办法在R 函数中调用上述SQL 函数,例如喜欢;

myfunc <- function(name) {
sqldf("select * from retrieve_data(name)")
}

myfunc('Bill')

任何指点将不胜感激,谢谢!

更新

按照@G 的建议,在sqldf 包中使用$fn 前缀。格洛腾迪克

myfunc2 <- function(name){
   fn$sqldf("select * from retrieve_data('$name')")
}

或者将上面的options 换成下面的代码来匹配@dickoa 建议的答案

require(RPostgreSQL)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv,
                 user="****",
                 password="****",
                 dbname="test_db",
                 host="localhost",
                 port=5432)

【问题讨论】:

标签: sql r postgresql sqldf nested-function


【解决方案1】:

诀窍是使用shQuotesprintf,但我确信有一些聪明的方法可以做到这一点。

library(sqldf)
library(RPostgreSQL)

options(sqldf.RPostgreSQL.user = "****",
        sqldf.RPostgreSQL.dbname = "****",
        sqldf.RPostgreSQL.host = "localhost",
        sqldf.RPostgreSQL.port = 5432)

myfunc <- function(name)
    sqldf(sprintf("select * from retrieve_data(%s)", shQuote(name)))

myfunc('Bill')
##   id name year_born nationality
## 1 A1 Bill      2001    American
## 2 A2 Bill      1991    American
## 3 A3 Bill      1995    American

如果你想避免引用字符串,那么你可以使用

drv <- dbDriver("PostgreSQL")
con <- dbConnect(drv, dbname = "tempdb")
myfunc2 <- function(name)
    dbGetQuery(con, "select * from retrieve_data($1)", name)

myfunc2("Bill")
##   id name year_born nationality
## 1 A1 Bill      2001    American
## 2 A2 Bill      1991    American
## 3 A3 Bill      1995    American

【讨论】:

  • 我想你会想要 postgresqlEscapeStrings 而不是 shQuote 因为你需要引用特定于 SQL(和 postgresql),而不是命令行 shell。 (虽然我不确定在这种情况下您对 con 参数使用什么。)
  • @BrianDiggs 这是主要问题,我不知道如何使用sqlf 找到con 类型的对象。我编辑并提出了一种更清洁的方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
  • 2020-02-12
相关资源
最近更新 更多