R:在自写包中使用 magrittr 管道运算符
Posted
技术标签:
【中文标题】R:在自写包中使用 magrittr 管道运算符【英文标题】:R: use magrittr pipe operator in self written package 【发布时间】:2015-03-12 21:31:02 【问题描述】:我想在我自己编写的包中使用magrittr
包中引入的管道运算符%>%
来链接dplyr
数据转换。 magrittr
在DESCRIPTION
文件中列为Import
。加载我自己的包并测试使用管道运算符的函数后,我收到以下错误消息:
函数名错误(参数,:找不到函数“%>%”
在函数源代码中将%>%
更改为magrittr::%>%
也无济于事,因为无法再构建包。
【问题讨论】:
我建议不要在包内的函数内使用管道运算符。它使调试变得更加困难(调用堆栈在管道中变得非常深)。对于包我只是覆盖一个临时变量,这使得测试更容易(想想:R 告诉你错误发生在哪一行)。管道非常适合交互式使用,但对于编程来说可能是一种负担。 【参考方案1】:如果您在Depends
中列出了magrittr
,它应该可以正常工作。但是,这是not advised。相反,您将magrittr
留在Imports
中,并将以下行添加到NAMESPACE
:
importFrom(magrittr,"%>%")
我建议阅读Writing R extensions。第 1.1.3 和 1.5.1 段涵盖了您的问题。
【讨论】:
@alexanderketh 在这种情况下,您应该点击答案旁边的绿色勾号将其标记为已接受。欢迎来到 SO! 如果您使用的是roxygen2
,您可以添加#' importFrom magrittr "%>%"
以在roxygenize()
期间自动填充NAMESPACE。
@RomanLuštrik,只是少了@,应该是#' @importFrom magrittr "%>%"
请注意,这只允许您在包内部使用%>%
。如果您的 API 要求用户使用 %>%
链接函数,他们仍然必须显式加载 magrittr
。解决此问题的一种方法是重新导出函数。这是an example 的操作方法。
这也是usethis包的作用,如here所提到的【参考方案2】:
现在有一种更简单的方法来支持您的包中的管道。精彩的包usethis
有功能use_pipe()
。您运行该函数一次,它会处理所有事情。 use_pipe()
函数在 usethis
文档中是这样描述的:
在你的包内部使用 magrittr 的管道是否需要设置 并为您的包的用户重新导出它:
将 magrittr 添加到说明中的“导入”
使用必要的 roxygen 模板创建 R/utils-pipe.R
【讨论】:
您是否将use_pipe()
行添加到您用于构建包的代码中?例如,我运行:usethis::use_description(usethis_description); usethis::use_build_ignore(directories); usethis::use_build_ignore(paste0(pkg_name, ".Rproj")); if (file.exists(file.path(pkg_path, "NAMESPACE"))) file.remove(file.path(pkg_path, "NAMESPACE")) ; devtools::document(pkg_path); devtools::check(pkg_path); devtools::load_all(pkg_path); devtools::install(pkg_path)
。我可以在开头添加use_pipe()
吗?
@Josh 您在开发包时使用了一次usethis
函数。然后,这些函数将必要的部分添加到构建指令和其他所有内容中。【参考方案3】:
另一种解决方案 - 使用 roxygen
包。它作为devtools
包的一部分实现。安装devtools
后,调用devtools::document()
将为您更新您的NAMESPACE
。它还自动构建带有文档的 .Rd 文件,这很方便。
您只需将#' @import packagename
格式的特殊注释添加到文件中以从该包中导入所有函数,或#' @importFrom packagename functionname
以导入函数。您可以在文件中包含任意数量的这些 cmets,因此您可以在每个文件的顶部放置一组它们,或者与需要外部函数的每个函数一起使用。
然后您运行 devtools::document()
并解析您的代码以查找这些 cmets,然后为您创建一个适当的 NAMESPACE
文件。很简单。
【讨论】:
当我这样做时,它会弄乱以下与 R 脚本中第一个函数的帮助文件有关的氧气 cmets。如何将全局氧气 cmets 与帮助文件分开? 我通常将 import cmets 与每个函数单独放在一起。这样,如果文件中的其他函数发生更改,您的导入将保持准确。所以没有全局定义。【参考方案4】:假设您使用 RStudio,Hadley 的 devtools
包,并在 DESCRIPTION
文件的 Imports 部分中列出了 magrittr
,以下是我为使 %>%
在我的包函数中工作所采取的步骤(s )。
首先,编写函数foo.R
:
#' Convert \codedata.frame to \codelist.
#'
#' @importFrom magrittr %>%
#' @name %>%
#' @rdname pipe
#' @export
#' @param x A \codedata.frame object.
#' @examples
#' my_result <- foo(iris)
#'
foo <- function(x)
x %>%
as.list()
其次,运行devtools::document()
。
第三,运行devtools::load_all()
。
this 之类的文件将在您的 R/
目录中创建,您的函数应该可以按预期工作。
【讨论】:
这里@name %>%
的目的是什么?以上是关于R:在自写包中使用 magrittr 管道运算符的主要内容,如果未能解决你的问题,请参考以下文章
python 导入自写包时ModuleNotFoundError 解决