R语言:在SQL语句中使用UDF

时间:2018-10-10 18:33:42

标签: r sqldf

我是R的新手,我正在尝试在SQL语句中使用UDF(通过sqldf 功能)。但是,我收到一个错误消息,说no such function

sqldf允许使用UDFs吗?

这是一个代码示例:

mySum <- function(x,y) { ret <- x+y return(ret) } 
data1=data.frame("var1"=1:3, "var2" = 5:7) 
View(data1) 
sSQL1 = "SELECT var1,var2,mySum(var1,var2) AS sum FROM data1" 
data2 <- sqldf(sSQL1,stringsAsFactors = FALSE) View(data2) 

在运行时,我收到一条错误消息:

Error in result_create(conn@ptr, statement) : no such function: mySum

1 个答案:

答案 0 :(得分:1)

SQLite扩展

如果您使用的是RSQLite后端,则RSQLite包含许多用C编写的功能,可从SQL使用这些功能,并且sqldf使这些功能可用。请参阅RSQLite软件包中的?initExtensions。如果其中之一已经满足您的要求,那可能是一个解决方案。

添加SQL函数

受支持的各种后端中,SQLite允许一个添加C函数,H2允许一个添加Java函数,MySQL和PostgreSQL允许一个添加使用CREATE FUNCTION用SQL编写的函数。

SQL语句的文本预处理

反引号通常,您不能将R混入SQL语句中。但是,可以使用fn$sqldf(...)然后使用$进行SQL的文本预处理,然后使用library(sqldf) mySum <- function(x, y) paste(x, y, sep = "+") fn$sqldf("select Time, demand, `mySum('Time', 'demand')` total from BOD", verbose = TRUE) 进行单值替换,或使用反引号替换R表达式的结果。例如,

sqldf: library(RSQLite)
sqldf: m <- dbDriver("SQLite")
sqldf: connection <- dbConnect(m, dbname = ":memory:")
sqldf: initExtension(connection)
sqldf: dbWriteTable(connection, 'BOD', BOD, row.names = FALSE)
sqldf: dbGetQuery(connection, 'select Time, demand, Time+demand total from BOD') <--
sqldf: dbDisconnect(connection)
  Time demand total
1    1    8.3   9.3
2    2   10.3  12.3
3    3   19.0  22.0
4    4   16.0  20.0
5    5   15.6  20.6
6    7   19.8  26.8

在以下示例中,我在行的末尾添加了一个箭头,该箭头显示了实际上传递给后端的语句。

?fn

请参见gsubfn软件包中的library,请注意sqldf会自动提供gsubfn软件包,因此您不需要mySum <- function(x, y) paste(x, y, sep = "+") total <- mySum("Time", "demand") fn$sqldf("select Time, demand, $total total from BOD") 语句。

美元符号以上是使用反引号的示例。这是使用$执行相同操作的示例。输出将是相同的。

2018-10-10 17:21:03.291 11777-20641/com.google.android.googlequicksearchbox:search W/ErrorProcessor: onFatalError, processing error from engine(4)
com.google.android.apps.gsa.shared.speech.a.g: Error reading from input stream
    at com.google.android.apps.gsa.staticplugins.recognizer.i.a.a(SourceFile:342)
    at com.google.android.apps.gsa.staticplugins.recognizer.i.a$1.run(SourceFile:1367)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at com.google.android.apps.gsa.shared.util.concurrent.a.ak.run(SourceFile:66)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
    at java.lang.Thread.run(Thread.java:761)
    at com.google.android.apps.gsa.shared.util.concurrent.a.ad$1.run(SourceFile:85)
 Caused by: com.google.android.apps.gsa.shared.exception.GsaIOException: Error code: 393238 | Buffer overflow, no available space.
    at com.google.android.apps.gsa.speech.audio.Tee.g(SourceFile:2531)
    at com.google.android.apps.gsa.speech.audio.ap.read(SourceFile:555)
    at java.io.InputStream.read(InputStream.java:101)
    at com.google.android.apps.gsa.speech.audio.al.run(SourceFile:362)
    at com.google.android.apps.gsa.speech.audio.ak$1.run(SourceFile:471)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at com.google.android.apps.gsa.shared.util.concurrent.a.ak.run(SourceFile:66)
    at com.google.android.apps.gsa.shared.util.concurrent.a.ax.run(SourceFile:139)
    at com.google.android.apps.gsa.shared.util.concurrent.a.ax.run(SourceFile:139)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
    at java.lang.Thread.run(Thread.java:761) 
    at com.google.android.apps.gsa.shared.util.concurrent.a.ad$1.run(SourceFile:85)