1

I have used the d3r package to convert an igraph object to JSON format like so:

# create small world network    
net <- sample_smallworld(size = 8, dim = 1, nei = 1, p = 0.33) 

# convert to json with directional edges   
data_json <- d3_igraph(as.directed(net)) 

This gives me the following output:

> data_json
{"nodes":[{"id":"0"},{"id":"1"},{"id":"2"},{"id":"3"},{"id":"4"},{"id":"5"},{"id":"6"},{"id":"7"}],"links":[{"source":"0","target":"1"},{"source":"1","target":"6"},{"source":"2","target":"3"},{"source":"3","target":"4"},{"source":"0","target":"4"},{"source":"3","target":"5"},{"source":"6","target":"7"},{"source":"0","target":"7"},{"source":"1","target":"0"},{"source":"6","target":"1"},{"source":"3","target":"2"},{"source":"4","target":"3"},{"source":"4","target":"0"},{"source":"5","target":"3"},{"source":"7","target":"6"},{"source":"7","target":"0"}],"attributes":{"name":"Watts-Strogatz random graph","dim":1,"size":8,"nei":1,"p":0.33,"loops":false,"multiple":false}} 

This is nearly what I want, but I need to configure two things:

  1. I want node IDs to start at 1, not 0.
  2. I want to remove the quotes around the node IDs in the links (the quotes are fine as they are in the nodes element), so that each link is written like this {"source": 1, "target": 2}, instead of {"source": "1", "target": "2"}

I could of course just do this manually for a small network like this, but that's tedious and not scalable for large networks. Is there better way I can this is R?

user72716
  • 263
  • 3
  • 22

1 Answers1

1

It's easy enough to convert the json into an R list and make the necessary changes to the data before writing back to json. Here's a function that should do the trick for the output of d3_igraph, using tools from the jsonlite package:

fix_d3_json <- function(json)
{
  dj <- jsonlite::fromJSON(data_json)
  dj$nodes$id   <- as.numeric(dj$nodes$id) + 1
  dj$links[[1]] <- as.numeric(dj$links[[1]]) + 1
  dj$links[[2]] <- as.numeric(dj$links[[2]]) + 1
  jsonlite::toJSON(dj)
}

So now you can do:

library(igraph)
library(d3r)

# create small world network    
net <- sample_smallworld(size = 8, dim = 1, nei = 1, p = 0.33) 

# convert to json with directional edges   
data_json <- d3_igraph(as.directed(net))

# Fix json
data_json <- fix_d3_json(data_json)

data_json
#> {"nodes":[{"id":1},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},
#> {"id":8}],"links":[{"source":1,"target":6},{"source":1,"target":2},
#> {"source":2,"target":3},{"source":3,"target":4},{"source":2,"target":6},
#> {"source":3,"target":6},{"source":6,"target":7},{"source":1,"target":7},
#> {"source":6,"target":1},{"source":2,"target":1},{"source":3,"target":2},
#> {"source":4,"target":3},{"source":6,"target":2},{"source":6,"target":3},
#> {"source":7,"target":6},{"source":7,"target":1}],"attributes":
#> {"name":["Watts-Strogatz random graph"],"dim":[1],"size":[8],"nei":[1],
#> "p":[0.33],"loops":[false],"multiple":[false]}}
Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • Great answer. Although your output looks exactly right, I had to make one small change in the function to have this work for me: `fix_d3_json <- function(json) { dj <- jsonlite::fromJSON(data_json) dj$nodes$id <- as.numeric(dj$nodes$id) + 1 dj$links[[1]] <- as.numeric(dj$links[[1]]) + 1 dj$links[[2]] <- as.numeric(dj$links[[2]]) + 1 jsonlite::toJSON(dj) }` ... Otherwise the links would reference node IDs 0-7, despite the ID attributes in the nodes element ranging from 1-8. – user72716 Jun 30 '20 at 13:26