加载自定义R包出现dbplyr覆盖S3方法提示如何解决
问题根因
这个S3方法覆盖提示和函数内部的调用逻辑无关,是包的依赖加载顺序错误导致的:print.tbl_lazy、print.tbl_sql两个S3方法是dbplyr提供的、用来覆盖dplyr同名基础实现的,如果包加载时先载入dplyr、后载入dbplyr,dbplyr注册方法时就会输出这个覆盖提示。
你当前用pkg::fun形式跨包调用函数,会在包加载阶段按引用顺序触发依赖包载入,很容易出现dplyr早于dbplyr加载的情况,就会弹出提示。
修复方案
按优先级选任意一种方式处理即可:
方案1:规范命名空间导入(推荐,符合R包开发规范)
- 首先确认包的
DESCRIPTION文件Imports字段同时声明了dplyr、dbplyr、DBI、odbc四个依赖,不要缺漏。 - 如果你用roxygen2维护命名空间(也就是靠函数前的
#'注释生成NAMESPACE文件),直接在dataset_to_tibble的注释块里补充导入声明,保证dbplyr的导入写在dplyr前面,roxygen2会按书写顺序生成NAMESPACE的导入规则,控制加载优先级:
#' From Dremio Dataset to Tidy Dataframe #' #' @importFrom dbplyr sql #' @importFrom DBI dbConnect dbDisconnect #' @importFrom odbc odbc #' @importFrom dplyr tbl collect #' @export dataset_to_tibble <- function(query, db_params) { query <- sql(query) channel <- do.call(dbConnect, c(odbc(), db_params)) on.exit(dbDisconnect(channel)) ds_lazy <- tbl(channel, query) collect(ds_lazy) }
改完后重新运行devtools::document()生成NAMESPACE即可,不需要再保留函数内的::调用前缀。
- 如果你手动维护NAMESPACE文件,直接把
importFrom(dbplyr, sql)这行放在所有dplyr相关的importFrom行之前就行。
方案2:手动控制加载顺序(不想改现有调用方式时用)
如果不想调整现有::的调用写法,可以在包的加载钩子里强制提前加载dbplyr。在包的R目录下新建zzz.R文件,写入以下内容:
.onLoad <- function(libname, pkgname) { # 提前加载dbplyr完成S3方法注册,避免覆盖提示 loadNamespace("dbplyr") }
这种方式不需要修改现有业务函数的代码,只要保证包加载时先载入dbplyr即可。
内容的提问来源于stack exchange,提问作者Filippe O. Gonçalves
相关产品推荐
相关产品推荐

