r - 为什么 R 报告相同函数的命名空间冲突?

标签 r namespaces shiny

我正在尝试创建 R 中包之间的命名空间冲突列表,但 conflicts()函数有一些奇怪的行为,例如函数 p在包裹中 shinyhtmltools (其中 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是其中之一,如果您有 shinyhtmltools随附的。

找出原因 shiny包含一个实际位于 htmltools 命名空间中的函数,你可以看看NAMESPACE shiny源中的文件.它包含以下几行
export(p)
import(htmltools)
export使函数对使用包的人可见。因此,在使用 library() 附加包后,您可以调用导出的函数。 . import(htmltools)确保 htmltools 中的所有导出函数可以被 shiny 中的函数使用.但是,它不会从 htmltools 生成函数提供给运行的人 library(shiny) .

因为 shinyhtmltools 导入所有函数(包括 p() )然后还导出 p() , p() (来自 htmltools )在 library(shiny) 之后可见.

您可以使用 identical() 检查两个冲突的对象是否实际上相同.这将显示函数 p()shinyhtmltools是一样的:
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/

相关文章:

r - 避免在失败的情况下使用tryCatch返回某些内容

C++ 命名空间 ofstream 不会写

R Shiny - 第 1 级没有此类指数

r - 将来自 shiny brushedPoints() 的输入转换为数据帧

在最近的更新之后,使用 Shinyjs 重置 event_data 似乎不再起作用

r - 计算和显示 ggplot2::geom_密度() 对象峰值的最佳方法是什么?

r - R 和 SPSS 线性模型结果之间的差异

R data.table 选择组 block 中的前一行

c++ - 一个类是一个命名空间

php - Yii 框架中的 Controller 实例化目录和命名空间