This package gives R functionality for mixed graphs, i.e.\ graphs with more than one kind of edge. Some standard edge types are built into the package, and can be seen by calling edgeTypes(). Others can be added by the user.

library(MixedGraphs)
edgeTypes()

Edges may be specified using either lists or adjacency matrices, giving the best of both worlds in terms of speed or storage requirements. We include flexible functions for finding adjacencies and connected components, so they can be used for any type of edge, even ones which have not yet been added to the package.

Graph Construction

Common Graphs

The functions makeGraphComplete(), makeGraphChain(), makeGraphCycle() and makeGraphStar() can be used to create commonly used graphs. Specifying just a graph size results in an undirected graph:

makeGraphStar(5)

Otherwise the optional argument type can be used to specify a different type of edge:

makeGraphComplete(4, "directed")

Character Input

For convenience, the function graphCr() allows graphs to be specified just by typing in their format. You can supply as many character arguments to the function as you like, which are then parsed and translated in to a mixed graph.

gr1 <- graphCr("1 -- 2 -> 3 <-> 4, 2 -> 4", "1 -- 4")
gr1

The edges should be in the same format as specified in edgeTypes(), save that adjacent dashes will be contracted: so --- and - are the same, as are <---> and <->.

Graphs can also be produced in representations used by other packages, for example (requires the graph package):

suppressMessages(require(graph))  ## otherwise fills page with conflicts
graphCr("1 -- 2 -- 3", format = "graphNEL")
detach(package:graph)

If all the vertex labels given are all numeric, then these are assumed to be their indices, and they are given the names x1, x2, etc. If any of the vertex labels is not numeric, then they are all taken as character representations, and their ordering becomes lexicographic.

graphCr("1 -- 2 -> x3 <-> 4, 2 -> 4", "1 -- 4")  # notice vertex ordering

So here the 3rd vertex has the name 4.

General Graphs

Graphs can most generally and safely be created using mixedgraph().
The main things to specify are n, the number of vertices, and edges, a named list of edges.

gr2 <- mixedgraph(5, edges=list(undirected=list(c(1,2),c(2,4),c(3,5))))

Each element of the edge list can be

Graph Manipulations

Subgraphs

The [ operator can be used to take induced subgraphs specified by their vertex numbers. For example,

gr3 <- gr1[c(1,3,4)]
gr3

An important point to note is that, although the subgraph only has three vertices, it (by default) retains all the information and positions of the vertices of the complete graph.

vnames(gr3)
gr3$v
# gr3[2]   will fail

This is computationally advantageous with vertex lists (since they do not have to be relabelled) and for later comparing subgraphs with their parent graph. This feature can be overridden with the drop argument if required.

Adding and removing edges

The addEdges() and removeEdges() functions can be used to modify an existing graph. Just supply a named list of edges as for initializing with mixedgraph():

addEdges(gr1, dir=eList(c(1,3)))
removeEdges(gr1, bi=eList(c(3,4)))

addEdges() stores edges in the same format as the original graph. Currently removeEdges() forces all edges to be stored as adjacency matrices: this will be corrected in future.

Edge Specifications

Edges can be specified in any of four ways, as an adjacency matrix (adjMatrix) which may be sparse, a list of adjacencies (adjList), a list of edges (eList), or a matrix with two rows, each of whose column corresponds to an edge (edgeMatrix).

These each have their own useful properties: adjacency matrices and lists generally allow things to be calculated most quickly with small or dense graphs, since R is well suited to working with matrices; finding the neighbours of a vertex is very fast. Conversely, using edge lists or edge matrices requires searching for the edges whose end points match the specification.

For larger sparse graphs the adjacency matrix may become burdensome and wasteful, even if represented sparsely itself; we can therefore use one of the other specifications. The edge matrix is the most efficient, but lists are intuitive and will in future be extended to allow hypergraphs.

We can force the use of adjacency matrices by applying withAdjMatrix() to a mixedgraph object.

Generic Relations

The functions adj(), grp(), groups() and mutilate() allow graphical operations to be performed on any edge type, as specified by the user.

Adjacency

adj() is used to find vertices which are adjacent to the specified vertex, with respect to whatever kind of edge. To find the neighbours of a (set of) vertices \code{v}, we just specify that we want adjacency via undirected edges:

adj(gr1, v = 2, etype = "undirected")

The built-in nb(graph, v) function is synonymous with adj(graph, v=v, etype="undirected").

For edges with direction, we can specify whether we want that direction to matter with the dir argument. The default is 0, which specifies either direction, and the alternatives 1 and -1 specify that the direction must be respectively the same or opposite to the default.gr1 So, for example, to find the children of a vertex we would use

adj(gr1, v = 2, etype = "directed", dir = 1)

The built-in ch(graph, v) function is synonymous with adj(graph, v=v, etype="directed", dir=1). Correspondingly using dir = -1 would give the parents. Using vector valued v means the definitions are applied disjuntively (i.e.\ it is the same as taking the union of the scalar outcomes).

We are also free to specify multiple edge types and directions:

adj(gr1, v = c(2,4), etype = c("undirected", "directed"), dir = c(0,-1))

Specific Versions

The functions pa(), ch(), sp() and nb() are available for the special cases of adjacencies generally called parents, children, spouses and neighbours respectively.

ch(gr1, 2)   # short cut for adj(gr1, v = 2, etype = "directed", dir = 1)

Adding Edge Types

New edge types can be added to the built in options.

Graph Format Conversion

The convert() function allows graphs to be transformed between the specifications used for different packages. (This function is not yet well tested.)

library(graph)
library(magrittr)
data(MAPKsig)
# convert(MAPKsig)

It can also be used to send objects to different formats:

amat <- convert(MAPKsig, format="ggm")
dim(amat)

The graph creation function graphCr also allows graphs to quickly be specified in other formats.

graphCr("1 -- 2 -- 4 -- 5, 2 -- 3 -- 5", format = "graphNEL")
graphCr("1 -> 2 -> 3 -> 4, 2 <-> 4", format = "ggm")

Automatic Evaluation

To save time if one needs functions from many packages, the %G% operator allows direct evaluation and takes care of the format conversion for you.

gr2 <- graphCr("1 -> 2 -> 3 -> 4 <- 2")
gr2 %G% degree()
degree(convert(gr2, "graphNEL"))

This is based on the idea of the pipe operator %>%. The %G% operator will try to determine which format is suitable for the code you provide.

MAPKsig %G% skeleton %G% (ggm::conComp)


rje42/MixedGraphs documentation built on March 20, 2024, 8:09 a.m.