Namespaces and name conflicts
来源:互联网 发布:网络层ip协议的特征 编辑:程序博客网 时间:2024/05/16 05:15
R packages ‘igraph’ and ‘network’ are good examples of two R packages providing similar but complementary functionalities for which there are a lot of name conflicts. As for now the ‘igraph’ package has a namespace while the ‘network’ package (version 1.4-1) does not. This became an issue when I was working on the ‘intergraph‘ package. Below is a note on how the fact that ‘igraph’ does and ‘network’ currently does not have a namespace affects using them simultaneously during an R session.
Loading and attaching ‘network’ and ‘igraph’ simultaneously (in this case ‘network’ first, ‘igraph’ second) gives
The following object(s) are masked from 'package:network':add.edges, add.vertices, %c%, delete.edges, delete.vertices,get.edge.attribute, get.edges, get.vertex.attribute, is.bipartite,is.directed, list.edge.attributes, list.vertex.attributes,set.edge.attribute, set.vertex.attribute
So let’s see how does it affect our work.
Attaching ‘network’ first, ‘igraph’ second
One of the conflicting functions is ‘add.edges’. When we call it from the console R starts looking for it in several places in a particular order. This can be inspected with ‘search’ function:
> search() [1] ".GlobalEnv" "package:igraph" "package:network" [4] "package:pnmath" "package:stats" "package:graphics" [7] "package:grDevices" "package:utils" "package:datasets"[10] "package:methods" "Autoloads" "package:base"
So R will look in global environment (aka Workspace) first and then in the code provided by the attached packages as shown. Consequently:
> # igraph version is on top> args(add.edges)function (graph, edges, ..., attr = list())NULL> # calling for version from network specifically> args(network::add.edges)function (x, tail, head, names.eval = NULL, vals.eval = NULL, ...)NULL
Because ‘network’ does not have a namespace some of its functions are masked by the copies from ‘igraph’. A call to some function from ‘network’ that uses one of those conflicting functions will use the version from the ‘igraph’ package (so trigger an error most likely) and not the correct version from ‘network’. For example:
> x <- as.network(matrix(sample(0:1, 9, replace=TRUE), 3, 3))Error in set.vertex.attribute(g, "na", rep(FALSE, n), 1:n) : Not a graph object
This tries to use ‘set.vertex.attribute’ from ‘igraph’ and not the correct one from ‘network’ because ‘igraph’ comes first on the search path as returned by ‘search()’.
Attaching ‘igraph’ first, ‘network’ second
First some clean-up then loading the packages
detach(package:network, unload=TRUE)detach(package:igraph, unload=TRUE)# igraph firstlibrary(igraph)library(network)
Now the network version of ‘add.edges’ is on top
> args(add.edges)function (x, tail, head, names.eval = NULL, vals.eval = NULL, ...)NULL
Version from ‘igraph’ can be called with ‘::’
> args(igraph::add.edges)function (graph, edges, ..., attr = list())NULL
Given that we attached ‘igraph’ first and ‘network’ second based on the previous section we could expect that this will brake the functioning of the ‘igraph’ package. Let’s see this with ‘V’ function in ‘igraph’ which calls ‘set.vertex.attribute’ (a name conflict with ‘network’).
> get("V<-")function (x, value){ if (!is.igraph(x)) { stop("Not a graph object") } if (!"name" %in% names(attributes(value)) || !"value" %in% names(attributes(value))) { stop("invalid indexing") } set.vertex.attribute(x, attr(value, "name"), index = value, value = attr(value, "value"))}<environment: namespace:igraph>
Let’s check that:
> g <- graph.full(3)> V(g)$type <- 1:3
And this works OK because for packages with namespaces R uses a little different searching mechanism. It searches in package namespace first, then among the functions imported by that package, then R base, and lastly in the “normal” search path (as from ‘search()’). See “Writing R Extensions”, last paragraph before the end of sub-section. Consequently, the correct version of ‘set.vertex.attribute’ is used.
Both packages have namespaces
If both packages have namespaces the errors like the one with ‘as.network’ shown above cannot happen. The code provided in the packages will work correctly as they will use their own copies of conflicting functions. Using the namespaced ‘network’ I made while creating ‘intergraph‘:
> library(network, lib="~/lib/R/2.11-dev")Loading ‘network’ from /home/mbojan/lib/R/2.11-dev/networkClasses for Relational DataVersion 1.4-1-1 created on 2008-11-17.copyright (c) 2005, Carter T. Butts, University of California-Irvine Mark S. Handcock, University of Washington David R. Hunter, Penn State University Martina Morris, University of WashingtonFor citation information, type citation("network").Type help("network-package") to get started.Modified by MBLoaded from “/home/mbojan/lib/R/2.11-dev”> library(igraph)Attaching package: 'igraph'The following object(s) are masked from 'package:network': add.edges, add.vertices, %c%, delete.edges, delete.vertices, get.edge.attribute, get.edges, get.vertex.attribute, is.bipartite, is.directed, list.edge.attributes, list.vertex.attributes, set.edge.attribute, set.vertex.attribute> net <- as.network(matrix(sample(0:1, 9, replace=TRUE), 3, 3))> net Network attributes: vertices = 3 directed = TRUE hyper = FALSE loops = FALSE multiple = FALSE bipartite = FALSE total edges= 2 missing edges= 0 non-missing edges= 2 Vertex attribute names: vertex.names adjacency matrix: 1 2 31 0 1 02 0 0 03 1 0 0
So, works OK even though we attached ‘network’ first and ‘igraph’ second.
Bottomline
- Name conflicts between R packages will be inevitable given the pace at which number of package on CRAN grow.
- Given that, using namespaces in packages is nowadays a necessity. See here how to do that.
- If one of the conflicting packages does not have a namespace it seems OK if you attach the namespaced package first and the non-namespaced one later.
- In case of name conflicts it is still the safest to use the :: operator and always specify what version (i.e. from which package) we want to use.
Filed under: networks, R
- Namespaces and name conflicts
- 使用Struts2遇到There is no action mapped for namespaces / and action name的问题
- 8.12 Namespaces and assemblies
- XPath and XML Namespaces
- Spring Schemas and Namespaces
- User namespaces and setgroups()
- Python Scopes and Namespaces
- ....conflicts with existing, non-compatible bean definition of same name and class
- conflicts with existing, non-compatible bean definition of same name and class
- SpringMVC conflicts with existing, non-compatible bean definition of same name and class 的解决办法
- SpringMVC 启动报错,conflicts with existing, non-compatible bean definition of same name and class ...
- [工作点滴]SpringMVC conflicts with existing, non-compatible bean definition of same name and class
- conflicts with existing, non-compatible bean definition of same name and class
- SpringMVC conflicts with existing, non-compatible bean definition of same name and class 的解决办法
- SpringMVC conflicts with existing, non-compatible bean definition of same name and class 的解决办法,sprin
- Spring Schemas and Namespaces(转)
- Naming Files, Paths, and Namespaces
- rails Controller Namespaces and Routing
- 实现APP弹幕功能——Android
- Android Loader 异步加载详解二:探寻Loader内部机制
- OpenGL播放视频的技术
- 恩格尔系数
- LintCode-二叉树专题总结
- Namespaces and name conflicts
- 课堂笔记四月二十日
- Android蓝牙使用(二)
- 第二章:Python速成 2.1 基础内容
- Java开发规范精要
- 基于SharePoint和Project Server 2013上快速搭建回归测试环境
- 数据库优化方案
- js入门(8)-window对象
- 替换空格