使用Python或R中的数据,我们经常加载几个包。在某些情况下,两个包(例如foo
和bar
)可能都包含某些功能(例如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不存在于base。"
我希望这个问题的一般答案与上面的from package import function
代码类似,但它不是。事实上,公认的(也是唯一的)答案只能解释为什么存在这个问题(而不是淡化这种贡献)。答案的评论中提供了一种解决方法,但该解决方法特定于该特定功能(reorder
)。
我是否可以从R中的特定包中仅导入特定功能?因此,我可以有意识地明确我的代码中所有函数调用的来源,并确保他们按照我认为他们正在做的事情进行操作?
答案 0 :(得分: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
包,这会强制您明确识别所有不明确函数调用的包:{{3} }
答案 1 :(得分:2)
您正在比较两种功能不同的语言。首先,您可以使用::
轻松地从包中引用函数,例如:
fortunes::fortune()
从fortune
包中调用fortunes
功能。
但你也必须小心这样做。因为取决于包的构造方式,最终可能会使用依赖于命名空间中的其他(非导出)函数的函数,但由于未加载命名空间,因此无法找到该函数。我自己使用来自例如mgcv
包的绘图函数来解决这个问题。这是使用library()
附加包的一个原因,正如Andrew Breza在他的回答中所说明的那样。至少使用::
构造调用的函数将按预期工作(99.9%)。
但是你链接到的问题不会被解决。问题是“糟糕的设计”,包装作者认为他需要一种S3方法来重新排序因子而不是特定于他的包的类。这样做为整个因子类注册了一个S3方法,因此改变了在因子上调用reorder()
的每个函数的行为。
由于这个问题是由软件包开发人员自己引起的,除了自己黑客入侵S3系统以找到所需的实际方法之外,你几乎无法做到这一点。
答案 2 :(得分:2)
尽管this答案是正确的,但不适用于诸如magrittr
的{{1}}和%>%
之类的中缀运算符。 %$%
程序包可享受待遇:
import
但是显然可以用于任何功能:
import::from(magrittr, "%$%")
请注意,“ [[import::from(foo, "do_stuff", "do_other_stuff")
]不适用于import
。它的名称是为了使像library
这样的调用具有表现力。”有关更多详细信息,请参见https://CRAN.R-project.org/package=import。
答案 3 :(得分:1)
从 R 4.0 开始,您还可以使用主 library()
函数执行此操作:
library(dplyr, include.only = c("select", "mutate"))
library(dplyr, exclude = c("filter", "lag"))