Rstudio 1.2 converting R object to JSON by r2d3 vs jsonlite

r2d3

#1

Hi,
I've tried working with Rstudio 1.2 and enjoyed D3.js integration in R notebooks. There is however a behavior of R to JSON conversion performed by r2d3 package that I'd like to discuss.

in pure D3 I'd read data from *.csv file with d3.csv() function and the resulting JSON object would look like:

[  { V1: value-1, V2: value-1, V3: value-1, ... Vn: value-1 }, 
   { V1: value-2, V2: value-2, V3: value-2, ... Vn: value-2 },
   ..........................................................  ]

Which is an array of objects where each object holds a row of original csv table. This is a format expected by D3.

When I read csv file in R and then pass R object to D3 chunk in R notebooks:

dataset <- read.csv(file)

{ d3 data=dataset } #markdown with R object passed to D3 chunk
It is converted to JSON as presented above. However, if I have several csv files:

dataset <- list()
dataset[[file1]] <- read.csv(file1)
dataset[[file2]] <- read.csv(file2)
dataset[[file3]] <- read.csv(file3)

this list of data frames will be converted in a different JSON layout:

{    file1 : {
       V1 : [value1, value2 ... valueN],
       V2 : [value1, value2 ... valueN],
       .....
       Vn : [value1, value2 ... valueN]
    },
     file2 : {
       V1 : [value1, value2 ... valueN],
       V2 : [value1, value2 ... valueN],
       ...
       Vn : [value1, value2 ... valueN]
   }, ...
}

Therefore if I take a subset data['file1'] it will not have the json representation expected by D3. Interestingly, R package jsonlite converts list of dataframe properly dataset <- toJSON(dataset)

{   file1: [
               { V1: value-1, V2: value-1, V3: value-1, ... Vn: value-1 }, 
               { V1: value-2, V2: value-2, V3: value-2, ... Vn: value-2 },
                ........................................................  
    ],
    file2: [
               { V1: value-1, V2: value-1, V3: value-1, ... Vn: value-1 }, 
               { V1: value-2, V2: value-2, V3: value-2, ... Vn: value-2 },
                ........................................................
    ]
}

Subsetting data['file1'] gives the same result as reading a single csv file and converting it to JSON.

Does r2d3 uses its own R to JSON conversion engine? What are other differences between r2d3 and jsonlite?

Thanks,


#2

You'll find everything about r2d3 data conversion to json in the vignette
https://rstudio.github.io/r2d3/articles/data_conversion.html

You'll find

  • what are the value of argument used by r2d2 in jsnonlite::toJSON
  • recommendations when custom conversion are needed
  • how to extend as_d3_data

Hope it helps.


#3

Based on the vignette the conversion happens in 2 steps R => JSON column => JSON row. This feels clunky since I can directly do R => JSON row. Apparently it also leads to odd results with nested structures such as a list of dataframes as in my example.

What happens if I pass R object manually converted to JSON? Does HTMLWidgets.dataframeToD3() attempts to re-format it anyway? It would be very useful to ensure passing exactly the same json representation from R to D3 code chunks.

I find it easier to troubleshoot R code because I can print to R console and explore object structures. I can't do it in the same way with D3 chunks - I have to open the notebook in a browser and use console.log() , JSON.stringify() and a browser console which requires constant knitting of R notebook after every code change. So it took me quite some time to realize my D3 input data were not properly formatted.


#4

Have you tried this? That's usually a good way to find out!