来自R中的[package] import [function]

问题描述 投票:5回答:3

使用Python或R中的数据,我们经常加载几个包。在某些情况下,两个包(例如foobar)可能各自包含一些功能(例如do_stuff)。

在Python中管理它以防止歧义或意外的方式如下:

from foo import do_stuff
from bar import other_function    # (does not load/import do_stuff() from bar)

在R中,我看到的所有代码都只导入了包含多个library(package_name)语句的整个包。我认为这会导致非常难以捕获的错误。例如,请参阅Reordering factor gives different results, depending on which packages are loaded。事实上,即使“没有掩蔽,因为在基础中不存在reorder.factor”,也会发生这种情况。

我预计这个问题的一般答案就像上面的from package import function代码,但事实并非如此。事实上,公认的(也是唯一的)答案只能解释为什么存在这个问题(而不是淡化这种贡献)。答案的评论中提供了一种解决方法,但该解决方法特定于该特定功能(reorder)。

有一般的方法我只能导入R中特定包的特定功能吗?因此,我可以有意识地明确我的代码中的所有函数调用来自何处,并确保它们执行我认为他们正在做的事情?

r function namespaces encapsulation
3个回答
6
投票

您可以使用package::function()构造明确告诉R哪个包应该用于给定函数。您甚至可以使用它来调用未使用library加载的包中的函数。

library(dplyr) # Has a function called filter()
library(plyr) # Also has a filter() function

dplyr::filter(foo)
plyr::filter(bar)

如果你想确保你最大限度地减少代码混淆的可能性,我强烈推荐使用conflicted包,这会强制你明确地识别所有模糊函数调用的包:https://www.tidyverse.org/articles/2018/06/conflicted/


2
投票

您正在比较两种功能不同的语言。首先,您可以使用::轻松地从包中引用函数,例如:

fortunes::fortune()

fortune包中调用fortunes函数。

但你也必须小心这样做。因为取决于包的构造方式,最终可能会使用依赖于命名空间中的其他(非导出)函数的函数,但由于未加载命名空间,因此无法找到该函数。我自己使用例如mgcv包的绘图函数来解决这个问题。这是使用library()附加包裹的一个原因,正如Andrew Breza在他的回答中所说明的那样。至少使用::构造调用的函数将按预期工作(99.9%的时间)。

但是你链接的问题不会被解决。问题是“糟糕的设计”,包装作者认为他需要一种S3方法来重新排序因子而不是特定于他的包的类。这样做为整个因子类注册了一个S3方法,因此改变了在一个因子上调用reorder()的每个函数的行为。

由于这个问题是由软件包开发人员自己造成的,除了自己黑客入侵S3系统以找到所需的实际方法之外,你几乎无法做到这一点。


2
投票

虽然this答案是正确的,但它对qixxswpoi的magrittr%>%等中缀运算符不起作用。 %$%套餐是一种享受:

import

但显然可以用于任何功能:

import::from(magrittr, "%$%")

请注意,“[import::from(foo, "do_stuff", "do_other_stuff") ]不适合与import一起使用。它被命名为像library表达的那样进行调用。”有关详细信息,请参阅import::from(pkg, fun1, fun2)

© www.soinside.com 2019 - 2024. All rights reserved.