# Serialize and unserialize in R. How to coerce similar objects?

**URL:** <https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288>\
**Category:** Usage\
**Tags:** R\
**Created:** [5 July 2022 19:24 UTC](https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288 "2022-07-05T19:24:25Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [5 July 2022 19:24 UTC](https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288/1 "2022-07-05T19:24:25Z")

</div>

I tried the following:

```auto
library(yaml)
library(igraph)

g1 <- make_star(7)
y1 <- as.yaml(g1)
g2 <- yaml.load(y1)

class(g1) # = igraph
class(g2) # = list

identical(str(g1), str(g2))	# true

```

g1 and g2 are structurally identical. But g1 has the class` igraph`. And g2 the class` list`. Is there an obvious way to convert g2 to `igraph` class.

---

<div class="post-metadata">

**Author:** ![tamas](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/tamas/32/1261_2.png) [@tamas](https://igraph.discourse.group/u/tamas)\
**Post date:** [5 July 2022 20:55 UTC](https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288/2 "2022-07-05T20:55:17Z")

</div>

No, there isn’t, because not all data is saved during the `as.yaml()` step:

```auto
> g1 <- make_star(7)
> unclass(g1)[[10]]
<environment: 0x10a0252e0>
> g2 <- yaml.load(as.yaml(g1))
> g2[[10]]
Error in g2[[10]] : subscript out of bounds

```

The part that is lost is a hidden R environment that stores all sorts of stuff about the graph that `igraph` itself needs:

```auto
> ls(unclass(g1)[[10]], all.names=T)
[1] ". __igraph_version__." "myid"

```

I guess you’ll need `saveRDS()` and `readRDS()` if you want to store an igraph object into a file in a way that preserves all R-specific stuff.

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [6 July 2022 07:59 UTC](https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288/3 "2022-07-06T07:59:08Z")

</div>

Then, is it possible to `"un.igraph"` an igraph object and retrieve the underlying list structure?  
Omitting the platform dependent data, but enough to reconstruct the graph.

As an example for graph g1: `g2 <- as.igraph(un.igraph(g1))`

If this is possible, then making a nice print of an igrapgh object is equivalent to printing a (nested) list neatly: prettyprint(un.igraph(g1)).

What I’m actually asking is a cross-platform definition of an igraph object.

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [6 July 2022 11:43 UTC](https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288/4 "2022-07-06T11:43:58Z")

</div>

> [@KeesP](#):
>
> What I’m actually asking is a cross-platform definition of an igraph object.

As we said before, `saveRDS / readRDS` provide a cross-platform way to losslessly serialize an R/igraph object.

You focus on “serializing igraph objects”, but since graph attributes can be arbitrary R objects, the only way to do this is to use a serialization that works for any R object. That naturally leads to `save` / `load` / `saveRDS` / `readRDS`.

---

<div class="post-metadata">

**Author:** ![szhorvat](https://yyz2.discourse-cdn.com/free1/user_avatar/igraph.discourse.group/szhorvat/32/3_2.png) [@szhorvat](https://igraph.discourse.group/u/szhorvat)\
**Post date:** [6 July 2022 11:49 UTC](https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288/5 "2022-07-06T11:49:21Z")

</div>

There are also functions like `dput` and `dump`, but as the `dput` documentation states,

> Deparsing an object is difficult, and not always possible. With the default `control` , `dput()` attempts to deparse in a way that is readable, but for more complex or unusual objects (see `dump` ), not likely to be parsed as identical to the original. Use `control = "all"` for the most complete deparsing;

None of this is igraph specific though. It all applies to any R object.

While `dput` is nice for getting a fairly accurate picture of what is in an R object, the documentation states that it cannot handle all objects and is not suitable for data transfer:

> This is **not** a good way to transfer objects between **R** sessions. `dump` is better, but the functions `save` and `saveRDS` are designed to be used for transporting **R** data, and will work with **R** objects that `dput` does not handle correctly as well as being much faster.

So, straight from the horse’s mouth (the R documentation), there’s your answer: use `save` or `saveRDS`.

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [6 July 2022 15:17 UTC](https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288/6 "2022-07-06T15:17:05Z")

</div>

Thanks for the very helpful comments.

What I’m trying to achieve is to distribute an object, but in a concise, human-readable form.  
With minimal dependencies on system and environment. So that others can experiment with the result. And in such a way that it can be published in limited space.

Building on the received input I arrived at:

```auto
library(igraph)
g1 <- make_star(7)
dput(g1) # transfer output to the code example

# code example
library(igraph)
s1 = r"---(
structure(list(7, TRUE,
 c(1, 2, 3, 4, 5, 6),
 c(0, 0, 0, 0, 0, 0),
 c(0, 1, 2, 3, 4, 5),
 c(0, 1, 2, 3, 4, 5),
 c(0, 0, 1, 2, 3, 4, 5, 6),
 c(0, 6, 6, 6, 6, 6, 6, 6),
 list(c(1, 0, 1),
 list(name = "In-star", mode = "in", center = 1),
 list(),
 list()) ),
 class = "igraph") 
)---"
g2 <- dget(rawConnection(charToRaw(s1)), keep.source=FALSE) 
g2 <- upgrade_graph(g2)
stopifnot(identical_graphs(g1, g2))

```

Dget doesn’t like `<envionment>` so I got rid of that.

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [7 July 2022 11:07 UTC](https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288/7 "2022-07-07T11:07:16Z")

</div>

Using a `raw vector` can be avoided, making it simpler.

```auto
library(igraph)
g1 <- make_star(7)
dput(g1) # transfer output to the code example

# code example
library(igraph)
s1 = deparse(
structure(list(7, TRUE,
 c(1, 2, 3, 4, 5, 6),
 c(0, 0, 0, 0, 0, 0),
 c(0, 1, 2, 3, 4, 5),
 c(0, 1, 2, 3, 4, 5),
 c(0, 0, 1, 2, 3, 4, 5, 6),
 c(0, 6, 6, 6, 6, 6, 6, 6),
 list(c(1, 0, 1),
 list(name = "In-star", mode = "in", center = 1),
 list(),
 list()) ),
 class = "igraph") 
)
g2 <- dget(textConnection(s1), keep.source=FALSE) 
g2 <- upgrade_graph(g2)
stopifnot(identical_graphs(g1, g2))

```

---

<div class="post-metadata">

**Author:** ![KeesP](https://avatars.discourse-cdn.com/v4/letter/k/2bfe46/32.png) [@KeesP](https://igraph.discourse.group/u/KeesP)\
**Post date:** [8 July 2022 11:13 UTC](https://igraph.discourse.group/t/serialize-and-unserialize-in-r-how-to-coerce-similar-objects/1288/8 "2022-07-08T11:13:58Z")

</div>

Triggered by Tamas’s example, I think it’s better to avoid the dput of the igraph object altogether by applying an unclass operation first.

```r
library(igraph)
g1 <- graph_from_literal(1 -+2) # non-empty igraph object
ug <- unclass(g1) # remove class igraph
ug[[10]] <- NULL # remove environment
dput(ug, stdout()) # output to console

```

```r
us <- list(2, TRUE, 0, 1, 0, 0, c(0, 1, 1), c(0, 0, 1), list(c(1, 0, 1), structure(list(), .Names = character(0)), list(name = c("1", "2")), structure(list(), .Names = character(0))))

g2 <- structure(us, class="igraph") # add class igraph
g3 <- upgrade_graph(g2) # and upgrade to current environment

```
