## Manipulating the nodes of a network structure

In many cases, the nodes of a Bayesian network are fixed quantity that is not subject to change; for instance, when learning its structure from data the nodes in the network correspond to the variables in the data. However, sometimes it can be useful to be able to manipulate the nodes in a network structure for studying its theoretical properties.

### Adding and removing nodes

**bnlearn** provides two functions to manipulate node sets: `add.node()`

and
`remove.node()`

. Both operate on objects of class `bn`

, and take the label of a node as their
second argument. `add.node()`

add the node to the network.

> library(bnlearn) > > dag = model2network("[A][B][C][F][G][D|C][H|C:F][E|D][I|A:F:H][J|E]") > larger.dag = add.node(dag, "K") > dag

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

> larger.dag

Random/Generated Bayesian network model: [A][B][C][F][G][K][D|C][H|C:F][E|D][I|A:F:H][J|E] nodes: 11 arcs: 8 undirected arcs: 0 directed arcs: 8 average markov blanket size: 2.00 average neighbourhood size: 1.45 average branching factor: 0.73 generation algorithm: Empty

The new node (`K`

above) added to `larger.dag`

is isolated; `larger.dag`

has the
same arcs as `dag`

.

`remove.node()`

works the other way round: it removes a node from the network, and in doing removes all
the arcs that are incident on that node.

> smaller.dag = remove.node(larger.dag, "I") > smaller.dag

Random/Generated Bayesian network model: [A][B][C][F][G][K][D|C][H|C:F][E|D][J|E] nodes: 10 arcs: 5 undirected arcs: 0 directed arcs: 5 average markov blanket size: 1.20 average neighbourhood size: 1.00 average branching factor: 0.50 generation algorithm: Empty

As a result, `smaller.dag`

has three fewer arcs because `A`

→ `I`

,
`F`

→ `I`

and `H`

→ `I`

are removed along with node
`I`

.

### Renaming nodes

The `nodes()`

function returns the labels of the nodes in a `bn`

object. (It does the same
for a `bn.fit`

object.)

> nodes(dag)

[1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J"

The assignment version of `nodes()`

replaces the labels with new ones, effectively renaming the nodes.

> nodes(dag) = c("X01", "X02", "X03", "X04", "X05", "X06", "X07", "X08", "X09", "X10") > dag

Random/Generated Bayesian network model: [X01][X02][X03][X06][X07][X04|X03][X08|X03:X06][X05|X04][X09|X01:X06:X08] [X10|X05] nodes: 10 arcs: 8 undirected arcs: 0 directed arcs: 8 average markov blanket size: 2.20 average neighbourhood size: 1.60 average branching factor: 0.80 generation algorithm: Empty

The labels of the nodes in the arc set are replaced as well for consistency.

> arcs(dag)

from to [1,] "X03" "X04" [2,] "X03" "X08" [3,] "X06" "X08" [4,] "X04" "X05" [5,] "X01" "X09" [6,] "X06" "X09" [7,] "X08" "X09" [8,] "X05" "X10"

In fact, the assignment version of `nodes()`

is an alias of the `rename.nodes()`

function,
which does the same thing but has a more discoverable and easy-to-guess name. Hence the above is equivalent to the
following.

> dag = rename.nodes(dag, names = c("X01", "X02", "X03", "X04", "X05", + "X06", "X07", "X08", "X09", "X10")) > dag

Random/Generated Bayesian network model: [X01][X02][X03][X06][X07][X04|X03][X08|X03:X06][X05|X04][X09|X01:X06:X08] [X10|X05] nodes: 10 arcs: 8 undirected arcs: 0 directed arcs: 8 average markov blanket size: 2.20 average neighbourhood size: 1.60 average branching factor: 0.80 generation algorithm: Empty

`Tue Nov 8 16:12:14 2022`

with **bnlearn**

`4.9-20221107`

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

.