## Interfacing with the **graph** R package

The **graph** package
(link)
is available from Bioconductor and it is one of the most popular packages to work on graphs (both
directed and undirected). It implements a variety of algorithms for random graph generation,
centrality statistics, graph distances, nodes and arcs manipulation utilities, and it provides a
strong foundation for the **Rgraphviz** package
(link). For
this reason, **bnlearn** implements functions to import and export network structures
to **graph** as:

`graphNEL`

objects, which encode the graph as a list in which each element refer to one of the nodes in the graph and contains a vector with its children;`graphAM`

objects, which encode the graph as a matrix in which the (*i*,*j*) cell is equal to one if there is an arc from the*i*th node to the*j*th node and zero otherwise.

### Exporting a network structure to **graph**

Exporting the objects is achieved with the conversion methods `as.graphNEL()`

and
`as.graphAM()`

.

> library(bnlearn) > > dag.bnlearn = random.graph(LETTERS[1:10]) > dag.bnlearn

Random/Generated Bayesian network model: [A][B][C][F][D|C][E|C][G|A:B:E][H|A:D][I|C:F:H][J|C:F:I] nodes: 10 arcs: 13 undirected arcs: 0 directed arcs: 13 average markov blanket size: 4.00 average neighbourhood size: 2.60 average branching factor: 1.30 generation algorithm: Full Ordering arc sampling probability: 0.2222222

> dag.graphNEL = as.graphNEL(dag.bnlearn) > dag.graphNEL

A graphNEL graph with directed edges Number of Nodes = 10 Number of Edges = 13

> dag.graphAM = as.graphAM(dag.bnlearn) > dag.graphAM

A graphAM graph with directed edges Number of Nodes = 10 Number of Edges = 13

Both methods accept objects of class `bn.fit`

as well as of class `bn`

,
and they implicitly call `bn.net()`

(link)
on the former to export them.

> dag.test = hc(learning.test) > dag.test

Bayesian network learned via Score-based methods model: [A][C][F][B|A][D|A:C][E|B:F] nodes: 6 arcs: 5 undirected arcs: 0 directed arcs: 5 average markov blanket size: 2.33 average neighbourhood size: 1.67 average branching factor: 0.83 learning algorithm: Hill-Climbing score: BIC (disc.) penalization coefficient: 4.258597 tests used in the learning procedure: 40 optimized: TRUE

> fitted = bn.fit(dag.test, learning.test) > as.graphNEL(fitted)

A graphNEL graph with directed edges Number of Nodes = 6 Number of Edges = 5

> as.graphAM(fitted)

A graphAM graph with directed edges Number of Nodes = 6 Number of Edges = 5

Undirected arcs are exported as a pair of directed arcs, that is, X_{i} —
X_{j} becomes {X_{i} → X_{j}, X_{i} ← X_{j}}.

> as.graphNEL(skeleton(dag.test))

A graphNEL graph with directed edges Number of Nodes = 6 Number of Edges = 10

### Importing a network structure from **graph**

Importing network structures works in the same way, with a conversion method `as.bn()`

.

> as.bn(dag.graphAM)

Random/Generated Bayesian network model: [A][B][C][F][D|C][E|C][G|A:B:E][H|A:D][I|C:F:H][J|C:F:I] nodes: 10 arcs: 13 undirected arcs: 0 directed arcs: 13 average markov blanket size: 4.00 average neighbourhood size: 2.60 average branching factor: 1.30 generation algorithm: Empty

> as.bn(dag.graphNEL)

Random/Generated Bayesian network model: [A][B][C][F][D|C][E|C][G|A:B:E][H|A:D][I|C:F:H][J|C:F:I] nodes: 10 arcs: 13 undirected arcs: 0 directed arcs: 13 average markov blanket size: 4.00 average neighbourhood size: 2.60 average branching factor: 1.30 generation algorithm: Empty

Note that as graphs are imported with `as.bn()`

they are checked to be acyclic, unless
the user specifies `check.cycles = FALSE`

.

> library(graph) > > m = matrix(rep(0, 9), nrow = 3, ncol = 3) > m[1, 2] = m[2, 3] = m[3, 1] = 1 > cyclic = graphAM(m, edgemode = "directed") > as.bn(cyclic)

## Error: the graphAM object contains directed cycles.

> as.bn(cyclic, check.cycles = FALSE)

Random/Generated Bayesian network model: [n1|n3][n2|n1][n3|n2] nodes: 3 arcs: 3 undirected arcs: 0 directed arcs: 3 average markov blanket size: 2.00 average neighbourhood size: 2.00 average branching factor: 1.00 generation algorithm: Empty

`Wed Nov 9 16:40:31 2022`

with **bnlearn**

`4.9-20221107`

and `R version 4.2.2 (2022-10-31)`

.