我试图在R中的包之间创建名称空间冲突列表,但是conflicts()函数有一些奇怪的行为,例如shiny和htmltools包中的函数p ( 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命名空间调用函数这一事实有关吗?
发布于 2015-12-18 20:57:13
函数conflicts只是检查搜索路径中包含在多个包中的名称。它不检查由这些名称表示的实际对象是否相同。
您可以使用objects() (也在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()中多个名称空间中出现的所有名称,如果附加了shiny和htmltools,p就是其中之一。
要了解为什么shiny包含htmltools名称空间中的函数,可以查看shiny源中的NAMESPACE文件。它包含以下几行
export(p)
import(htmltools)export使一个函数对使用包的人可见。因此,在您使用library()附加了一个包之后,您可以调用导出的函数。import(htmltools)确保htmltools中的所有导出函数都可以由shiny中的函数使用。但是,它并没有使htmltools的函数对运行library(shiny)的人可用。
因为shiny从htmltools (包括p())导入所有函数,然后导出p(),所以p() (从htmltools)在library(shiny)之后是可见的。
您可以使用identical()检查两个冲突的对象是否实际上是相同的。这将显示shiny和htmltools中的函数htmltools是相同的:
library(shiny)
library(htmltools)
identical(htmltools::p, shiny::p)
## [1] TRUE另一方面,dplyr定义了一个不同于stats中的函数filter()
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)https://stackoverflow.com/questions/34360576
复制相似问题