Interfacing with the gRain R package

The gRain package (link) is available from CRAN and provides the only implementation of exact inference in R; currently it only supports discrete Bayesian networks. The main data structure in gRain is the grain class, which stores a fitted Bayesian network as a list of conditional probability tables (much like bnlearn's objects) and makes it possible for setEvidence() and querygrain() to perform posterior inference via belief propagation.

Exporting a fitted Bayesian networks to gRain objects can be exported with the conversion method as.grain().

> library(bnlearn)
> dag = hc(learning.test)
> fitted.bnlearn =, learning.test)
> fitted.grain = as.grain(fitted.bnlearn)
> fitted.grain
Independence network: Compiled: TRUE Propagated: FALSE
  Nodes: chr [1:6] "A" "B" "C" "D" "E" "F"

Only discrete networks can be exported, since gRain does not support networks with other parametric assumptions.

> dag.gbn = hc(gaussian.test)
> fitted.gbn =, gaussian.test)
> as.grain(fitted.gbn)
## Error: the gRain package only supports discrete networks.

The other important limitation of gRain, compared to bnlearn, is that it does not allow for conditional probabilities to be NaN. (This happens when estimating them via maximum likelihood and some parent configurations are not observed in the data.) In that case as.grain() will give a warning and replace the NaNs with uniform distributions, much like the Bayesian posterior estimator would.

> fitted.sparse =, learning.test[1:10, ])
> as.grain(fitted.sparse)
## Warning in NaN conditional probabilities in D, replaced
## with a uniform distribution.
Independence network: Compiled: TRUE Propagated: FALSE
  Nodes: chr [1:6] "A" "B" "C" "D" "E" "F"

Importing a network structure from gRain

Importing network structures works in the same way, with a conversion method

> fitted.import =
> all.equal(fitted.bnlearn, fitted.import)
[1] TRUE

For convenience, bnlearn also provides an conversion function that returns the network structure underlying the grain object as a bn object.

> dag.import =
> all.equal(dag, dag.import)
[1] TRUE

Note that by default disregards any evidence that has been set in the grain object with setEvidence(). So, for instance, setting B equal to b does not have any effect on the conditional probability table for node B in the returned object.

> library(gRain)
> fitted.with.evidence = setEvidence(fitted.grain, node = "B", state = "b")

  Parameters of node B (multinomial distribution)

Conditional probability table:

B            a          b          c
  a 0.85611511 0.44491018 0.11492178
  b 0.02517986 0.22095808 0.09446450
  c 0.11870504 0.33413174 0.79061372

Using the argument including.evidence will modify the conditional probability table to reflect the evidence in the grain object.

>, including.evidence = TRUE)$B

  Parameters of node B (multinomial distribution)

Conditional probability table:

B   a b c
  a 0 0 0
  b 1 1 1
  c 0 0 0
Last updated on Wed Nov 9 16:40:00 2022 with bnlearn 4.9-20221107 and R version 4.2.2 (2022-10-31).