调试:!SELECT: 没有这样的运算符'normalize2'

Debugging: !SELECT: no such operator 'normalize2'

我想在 R 中创建多个函数以 运行 嵌入到 MonetDB 中。

函数 1(在查询的 select 部分调用)

dbGetQuery(conn, "DROP FUNCTION normalize;")
functionDef <- paste(
    "CREATE FUNCTION normalize(welltype STRING, data_column DOUBLE) RETURNS TABLE (i DOUBLE) LANGUAGE R {", 
    "idx <- which(welltype == 'LC')",
    "100 * data_column / median(data_column[idx])",
    "};", sep = "\n")
dbGetQuery(conn, functionDef)

使用示例

stmt <- "SELECT barcode, normalize(welltype_code, data_column1) FROM hcs;"
dbGetQuery(conn, stmt)

这很好用。

函数 2(在查询的 select 部分调用)

所以我想创建一个更高级的版本:

dbGetQuery(conn, "DROP FUNCTION normalize2;")
functionDef <- paste(
    "CREATE FUNCTION normalize2(barcode DOUBLE, welltype STRING, data_column DOUBLE) RETURNS TABLE (i DOUBLE) LANGUAGE R {", 
    "idx <- which(welltype == 'LC')",
    "100 * data_column / median(data_column[idx])",
    "};", sep = "\n")
dbGetQuery(conn, functionDef)

如您所见,到目前为止我所做的唯一更改是向函数添加了一个额外的参数。

然而,这失败了:

使用示例:

stmt <- "SELECT normalize2(barcode, welltype_code, data_column1) FROM hcs;"
dbGetQuery(conn, stmt)

结果:

 !SELECT: no such operator 'normalize2'

我查了一下,类型都没有问题:

barcode = DOUBLE
welltype_code = CHARACTER LARGE OBJECT
data_column1 = DOUBLE

然后我尝试了另一种方式,我看到了 MonetDB 中使用的函数。

使用子查询的结果调用函数

在这种情况下,我们将 SELECT 查询的结果提供给函数,而不是在查询的 selection 部分中使用它。

dbGetQuery(conn, "SELECT * FROM normalize2( (SELECT barcode, welltype_code, data_column1 FROM hcs) );")

有效!

但是,我需要在 table 的许多列上执行此操作。 使用第一种语法,我可以执行以下操作:

stmt <- "SELECT barcode, normalize(welltype_code, data_column1), normalize(welltype_code, data_column2) FROM hcs;"
dbGetQuery(conn, stmt)

除了加入中间 table 之外,我不确定如何使用新的查询结构实现类似的结果。 (并且由于必须在数千列上完成此操作,因此这可能不是最有效的策略)

所以我的问题归结为: 为什么:

SELECT normalize(welltype_code, data_column1) FROM hcs;

工作? 而不是:

SELECT normalize2(barcode, welltype_code, data_column1) FROM hcs;

其次,使用子查询调用它有什么区别。 如果这是使用它的唯一方法,欢迎指导如何编写可以有效地应用于不同数量列的函数。

测试数据:

dput输出:

structure(list(barcode = c(110000184638, 110000184638, 110000184638, 
110000184638, 110000184638, 110000184638, 110000184638, 110000184638, 
110000184638, 110000184638), welltype_code = c("LC", "LC", "LC", 
"LC", "LC", "LC", "LC", "LC", "LC", "LC"), data_column1 = c(0.344772189855576, 
0.334164410829544, 0.315271258354187, 0.320378184318542, 0.322041183710098, 
0.32072114944458, 0.29565417766571, 0.321962893009186, 0.298929244279861, 
0.323741465806961)), .Names = c("barcode", "welltype_code", "data_column1"
), row.names = c(NA, 10L), class = "data.frame")

投影函数(在 SELECT 之后使用的函数)只能 return 单列。因此,normalize2 的定义应该是

CREATE FUNCTION normalize2(barcode DOUBLE, welltype STRING, data_column DOUBLE)
RETURNS DOUBLE LANGUAGE R { ...

而不是

CREATE FUNCTION normalize2(barcode DOUBLE, welltype STRING, data_column DOUBLE) 
RETURNS TABLE (i DOUBLE) LANGUAGE R { ...

希望对您有所帮助