首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么R会为相同的函数报告名称空间冲突?

为什么R会为相同的函数报告名称空间冲突?
EN

Stack Overflow用户
提问于 2015-12-18 17:07:29
回答 1查看 995关注 0票数 0

我试图在R中的包之间创建名称空间冲突列表,但是conflicts()函数有一些奇怪的行为,例如shinyhtmltools包中的函数p ( shiny导入的):

代码语言:javascript
复制
> 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),这个函数将被列为两个包之间的冲突。为什么这被列为冲突,是否有办法检测这种类型的“冲突”?这与您可以直接从shinyhtmltools命名空间调用函数这一事实有关吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-18 20:57:13

函数conflicts只是检查搜索路径中包含在多个包中的名称。它不检查由这些名称表示的实际对象是否相同。

您可以使用objects() (也在conflicts()中使用)或ls()查看包名称空间中的对象的名称。例如:

代码语言:javascript
复制
head(objects("package:shiny"), 10)
 ## [1] "a"                "absolutePanel"    "actionButton"     "actionLink"       "addResourcePath" 
 ## [6] "animationOptions" "as.shiny.appobj"  "basicPage"        "bootstrapPage"    "br"

如果你跑

代码语言:javascript
复制
which(objects("package:shiny") == "p")
which(objects("package:htmltools") == "p")

您将看到shinyhtmltools的命名空间都包含一个名为p的对象。conflicts只需检查search()中多个名称空间中出现的所有名称,如果附加了shinyhtmltoolsp就是其中之一。

要了解为什么shiny包含htmltools名称空间中的函数,可以查看shiny源中的NAMESPACE文件。它包含以下几行

代码语言:javascript
复制
export(p)
import(htmltools)

export使一个函数对使用包的人可见。因此,在您使用library()附加了一个包之后,您可以调用导出的函数。import(htmltools)确保htmltools中的所有导出函数都可以由shiny中的函数使用。但是,它并没有使htmltools的函数对运行library(shiny)的人可用。

因为shinyhtmltools (包括p())导入所有函数,然后导出p(),所以p() (从htmltools)在library(shiny)之后是可见的。

您可以使用identical()检查两个冲突的对象是否实际上是相同的。这将显示shinyhtmltools中的函数htmltools是相同的:

代码语言:javascript
复制
library(shiny)
library(htmltools)
identical(htmltools::p, shiny::p)
## [1] TRUE

另一方面,dplyr定义了一个不同于stats中的函数filter()

代码语言:javascript
复制
library(dplyr)
identical(dplyr::filter, stats::filter)
## [1] FALSE

最后,让我提出一种检查方法,一些冲突(即出现在几个附加包中的名称)是否是“真正的”冲突。所谓“真实的”,我的意思是共享名称的对象是不一样的。因此,在上面的例子中,filter()将是一个“真实的”冲突,而"p“则不是。以下函数返回“真实”冲突的TRUE,否则返回false:

代码语言:javascript
复制
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))
}

您可以一次检查所有相互冲突的名称。

代码语言:javascript
复制
sapply(conflicts(), is_real_conflict)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34360576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档