我是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
答案 0 :(得分:1)
如果您使用的是RSQLite后端,则RSQLite包含许多用C编写的功能,可从SQL使用这些功能,并且sqldf使这些功能可用。请参阅RSQLite软件包中的?initExtensions
。如果其中之一已经满足您的要求,那可能是一个解决方案。
受支持的各种后端中,SQLite允许一个添加C函数,H2允许一个添加Java函数,MySQL和PostgreSQL允许一个添加使用CREATE FUNCTION用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)