dplyr:连接到外部数据库时在 summarise() 中使用自定义函数

Posted

技术标签:

【中文标题】dplyr:连接到外部数据库时在 summarise() 中使用自定义函数【英文标题】:dplyr: use a custom function in summarize() when connected to external database 【发布时间】:2021-05-26 20:57:57 【问题描述】:

在使用 dplyr 从外部数据库中提取数据时,是否可以在摘要语句中使用自定义函数? 我无法制作可用的虚拟数据,因为这是特定于数据库的,但假设您有一个包含三个字段的表:product、true_positive 和 all_positive。这是我要使用的代码:

getPrecision <- function(true_positive, all_positive)
  if_else(sum(all_positive, na.rm = TRUE) == 0, 0,
          (sum(true_positive) / sum(all_positive , na.rm = TRUE)))


database_data %>%
    group_by(product) %>%
    summarize(precision = getPrecision(true_positive, all_positive)) %>% collect

这是错误: postgresqlExecStatement(conn, statement, ...) 中的错误: RS-DBI 驱动程序:(无法检索结果:错误:函数 getprecision(integer, integer) 不存在

【问题讨论】:

可以尝试用all_positivetrue_positive 包装,未测试 【参考方案1】:

要了解错误消息,您可以使用show_query 而不是collect 来查看发送到数据库的SQL 代码:

database_data %>%
    group_by(product) %>%
    summarize(precision = getPrecision(true_positive, all_positive)) %>%  
    show_query

<SQL>
SELECT "product", getPrecision("true_positive", "all_positive") AS "precision"
FROM "database_table"
GROUP BY "product"

如您所见,这个SQL 期望getPrecision 函数在服务器上可用,但事实并非如此。

一个潜在的解决方案是先收集表数据,然后在R 客户端中应用此功能:

database_data %>%
    collect %>%
    group_by(product) %>%
    summarize(precision = getPrecision(true_positive, all_positive)) 

如果这不可行,因为表太大,你必须在服务器上实现SQL中的功能:

SELECT 
  "product", 
  CASE WHEN sum(all_positive)=0 THEN 0 ELSE sum(true_positive)/sum(all_positive) END AS "precision"
FROM "database_table"
GROUP BY "product"

【讨论】:

以上是关于dplyr:连接到外部数据库时在 summarise() 中使用自定义函数的主要内容,如果未能解决你的问题,请参考以下文章

使用 RPostgreSQL 和 dplyr 将 R 连接到 Redshift 的理论是啥

如何使用 dplyr 和 RPostgreSQL 将 r 连接到 redshift?

连接到 RDBMS 时在 Spark 中进行分区

连接到互联网时在主屏幕上显示进度轮 [Android]

R 在使用 dplyr 或 RPostgreSQL 的模式下访问 redshift 表

如何在 R 中使用 DBI 连接到 bigquery 数据库后列出表的字段