Quantcast
Channel: Wei Luo » Home
Viewing all articles
Browse latest Browse all 14

R to JSON for D3.js and Protovis

$
0
0

D3.js and Protovis use the file format JSON to hold input data. In particular, the most natural format is an array of JSON objects, such as

[ { "Petal.Width" : 0.2, "Species" : "setosa" }, { "Petal.Width" : 1.3, "Species" : "versicolor" }, { "Petal.Width" : 1.8, "Species" : "virginica" } ]

There seems to be no readily available tool for transform a R data frame into a JSON array such that each row in R becomes an JSON object in the array. The rjson package actually converts a data frame into a JSON hashmap, in which each column of the data frame becomes a named array (see below).

{"Petal.Width":[0.2,1.3,1.8],"Species":["setosa","versicolor","virginica"]}

Similar question has been asked at StackOverflow and a solution proposed. The solution involves transposing the data frame before feeding to the toJSON funciton in the rjson package.

toJSON(data.frame(t(dtf)))

The solution works for data frames with character strings. However, when a data frame has numeric columns, the final result will contain problematic quotation marks around numeric values, which makes the JSON file not suitable for D3.js or Protovis (see below). This is particularly problematic when the numbers are extremely large or small, in which case scientific notation is likely used by R to format numeric values.

{"X50":{"Petal.Width":"0.2","Species":"setosa"},"X100":{"Petal.Width":"1.3","Species":"versicolor"},"X150":{"Petal.Width":"1.8","Species":"virginica"}}

To address this problem, I wrote a function that will convert a data frame directory to a JSON string.

toJSONarray <- function(dtf){
clnms <- colnames(dtf)

name.value <- function(i){
quote <- '';
if(class(dtf[, i])!='numeric'){
quote <- '"';
}

paste('"', i, '" : ', quote, dtf[,i], quote, sep='')
}

objs <- apply(sapply(clnms, name.value), 1, function(x){paste(x, collapse=', ')})
objs <- paste('{', objs, '}')

res <- paste('[', paste(objs, collapse=', '), ']')

return(res)
}

With this function, the output will work in D3.js and Protovis:

[ { "Petal.Width" : 0.2, "Species" : "setosa" }, { "Petal.Width" : 1.3, "Species" : "versicolor" }, { "Petal.Width" : 1.8, "Species" : "virginica" } ]



Viewing all articles
Browse latest Browse all 14

Trending Articles