我正在尝试创建 R 中包之间的命名空间冲突列表,但 conflicts()
函数有一些奇怪的行为,例如函数 p
在包裹中 shiny
和 htmltools
(其中 shiny
进口):
> require(shiny)
> ## print source from shiny namespace...
> shiny::p
function (...)
tags$p(...)
<environment: namespace:htmltools>
> require(htmltools)
> ## print source from htmltools namespace...
> htmltools::p
function (...)
tags$p(...)
<environment: namespace:htmltools>
所以来源为
p
完全相同,甚至来自这两个包的相同命名空间(帮助文件也相同),但是如果您运行 conflicts(detail = TRUE)
,此功能被列为两个包之间的冲突。为什么这被列为冲突,有没有办法检测这种类型的“冲突”?这是否与您可以直接从 shiny
调用该函数的事实有关?或 htmltools
命名空间?
最佳答案
函数conflicts
只需检查搜索路径中包含在多个包中的名称即可。它不检查由这些名称表示的实际对象是否相同。
您可以使用 objects()
查看包 namespace 中对象的名称。 (也在 conflicts()
中使用)或 ls()
.例如:
head(objects("package:shiny"), 10)
## [1] "a" "absolutePanel" "actionButton" "actionLink" "addResourcePath"
## [6] "animationOptions" "as.shiny.appobj" "basicPage" "bootstrapPage" "br"
如果你跑
which(objects("package:shiny") == "p")
which(objects("package:htmltools") == "p")
你会看到
shiny
的命名空间和 htmltools
两者都包含一个名为 p
的对象. conflicts
只需检查 search()
中出现在多个命名空间中的所有名称和 p
是其中之一,如果您有 shiny
和 htmltools
随附的。找出原因
shiny
包含一个实际位于 htmltools
命名空间中的函数,你可以看看NAMESPACE
shiny
源中的文件.它包含以下几行export(p)
import(htmltools)
export
使函数对使用包的人可见。因此,在使用 library()
附加包后,您可以调用导出的函数。 . import(htmltools)
确保 htmltools
中的所有导出函数可以被 shiny
中的函数使用.但是,它不会从 htmltools
生成函数提供给运行的人 library(shiny)
.因为
shiny
从 htmltools
导入所有函数(包括 p()
)然后还导出 p()
, p()
(来自 htmltools
)在 library(shiny)
之后可见.您可以使用
identical()
检查两个冲突的对象是否实际上相同.这将显示函数 p()
在 shiny
和 htmltools
是一样的:library(shiny)
library(htmltools)
identical(htmltools::p, shiny::p)
## [1] TRUE
另一方面,
dplyr
定义一个函数 filter()
与 stats
中的不同:library(dplyr)
identical(dplyr::filter, stats::filter)
## [1] FALSE
最后,让我提出一种方法来检查某些冲突(即出现在几个附加包中的名称)是否是“真正的”冲突。通过“真实”,我的意思是共享名称的对象不相同。所以,
filter()
在上面的例子中将是一个“真正的”冲突,而“p”则不是。以下函数返回 TRUE
对于“真正的”冲突,否则为 false:is_real_conflict <- function(conf_obj) {
# get list of all conflicts
conf_all <- conflicts(detail = TRUE)
# get names of packages that contain an object with name conf_obj
conf_pck <- names(conf_all)[sapply(conf_all, function(pck) conf_obj %in% pck)]
# get the actual objects associated with these names
objs <- lapply(conf_pck, function(ns) get(conf_obj, envir = as.environment(ns)))
# compare each of the objects to the first one
comp <- sapply(objs, identical, objs[[1]])
# the following returns FALSE only if all the objects are the same
return (!all(comp))
}
您可以使用以下命令一次性检查所有冲突的名称
sapply(conflicts(), is_real_conflict)
关于r - 为什么 R 报告相同函数的命名空间冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34360576/