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

时间:2016-03-21 09:15:42

标签: r monetdb

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

功能1(在查询的选择部分中调用)

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(在查询的选择部分中调用)

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

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查询的结果,而不是在查询的列选择部分中使用它。

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

有效!

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

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

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

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

SELECT normalize(welltype_code, data_column1) FROM hcs;

工作? 而不是:

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

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

测试数据:

输出输出:

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")

1 个答案:

答案 0 :(得分:2)

投影函数(在SELECT之后使用的投影函数)只能返回单个列。因此,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 { ...

希望这有帮助