Some simple examples to compare behavior and performance of JSON packages in R.
all.equal(mtcars, rjson::fromJSON(rjson::toJSON(mtcars)))
[1] "Attributes: < names for target but not for current >"
[2] "Attributes: < Length mismatch: comparison on first 0 components >"
all.equal(mtcars, RJSONIO::fromJSON(RJSONIO::toJSON(mtcars)))
[1] "Attributes: < names for target but not for current >"
[2] "Attributes: < Length mismatch: comparison on first 0 components >"
all.equal(mtcars, jsonlite::fromJSON(jsonlite::toJSON(mtcars)))
[1] TRUE
(x <- matrix(1:6, 2))
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
rjson::fromJSON(rjson::toJSON(x))
[1] 1 2 3 4 5 6
RJSONIO::fromJSON(RJSONIO::toJSON(x))
[[1]]
[1] 1 3 5
[[2]]
[1] 2 4 6
jsonlite::fromJSON(jsonlite::toJSON(x))
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
x <- list(foo = 123, bar= 456)
rjson::fromJSON(rjson::toJSON(x))
$foo
[1] 123
$bar
[1] 456
RJSONIO::fromJSON(RJSONIO::toJSON(x))
foo bar
123 456
jsonlite::fromJSON(jsonlite::toJSON(x))
$foo
[1] 123
$bar
[1] 456
rjson::fromJSON(rjson::toJSON(c(1,2,NA,4)))
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] "NA"
[[4]]
[1] 4
RJSONIO::fromJSON(RJSONIO::toJSON(c(1,2,NA,4)))
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
NULL
[[4]]
[1] 4
jsonlite::fromJSON(jsonlite::toJSON(c(1,2,NA,4)))
[1] 1 2 NA 4
x <- list("\b\f\n\r\t" = "\b\f\n\r\t")
identical(x, rjson::fromJSON(rjson::toJSON(x)))
[1] TRUE
identical(x, RJSONIO::fromJSON(RJSONIO::toJSON(x)))
[1] FALSE
identical(x, jsonlite::fromJSON(jsonlite::toJSON(x)))
[1] TRUE
rjson::fromJSON('[1,2,boo",4]')
Error: unexpected character 'b'
RJSONIO::fromJSON('[1,2,boo",4]')
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
NULL
jsonlite::fromJSON('[1,2,boo",4]')
Error: lexical error: invalid char in json text.
[1,2,boo",4]
(right here) ------^
json = '["\\u5bff\u53f8","Z\\u00fcrich", "\\u586B"]'
rjson::fromJSON(json)
[1] "寿司" "Zürich" "填"
RJSONIO::fromJSON(json)
[1] "\xff司" "Z\xfcrich" "k"
jsonlite::fromJSON(json)
[1] "寿司" "Zürich" "填"
Only RJSONIO and jsonlite have functionality to validate or prettify JSON:
x <- list(foo = c("hi", "hello"), bar=1:3)
cat(RJSONIO::toJSON(x, pretty = TRUE))
{
"foo" : [
"hi",
"hello"
],
"bar" : [
1,
2,
3
]
}
cat(jsonlite::toJSON(x, pretty = TRUE))
{
"foo": [
"hi",
"hello"
],
"bar": [
1,
2,
3
]
}
RJSONIO::isValidJSON(RJSONIO::toJSON(x), asText = TRUE)
[1] TRUE
jsonlite::validate(jsonlite::toJSON(x))
[1] TRUE
RJSONIO uses significant digits, whereas jsonlite uses decimal digits. rjson does not support this.
rjson::toJSON(pi)
[1] "3.14159265358979"
RJSONIO::toJSON(pi, digits=4)
[1] "[ 3.142 ]"
jsonlite::toJSON(pi, digits=4)
[3.1416]
Only RJSONIO and jsonlite give control over vector simplification. rjson always simplifies if possible.
json <- '[1,2,3,4]'
RJSONIO::fromJSON(json)
[1] 1 2 3 4
RJSONIO::fromJSON(json, simplify = FALSE)
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
[[4]]
[1] 4
jsonlite::fromJSON(json)
[1] 1 2 3 4
jsonlite::fromJSON(json, simplifyVector = FALSE)
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 3
[[4]]
[1] 4
rjson::fromJSON(json)
[1] 1 2 3 4
Comparing performance is a bit difficult because different packages do different things. The rjson
package has no options to control conversion, so the only way to benchmark common functionality is by trying to mimic rjson
:
library(microbenchmark)
data(diamonds, package="ggplot2")
microbenchmark(
rjson::toJSON(diamonds),
RJSONIO::toJSON(diamonds),
jsonlite::toJSON(diamonds, dataframe = "column"),
times = 10
)
Unit: milliseconds
expr min lq median uq max neval
rjson::toJSON(diamonds) 294.9 296.5 297.4 298.5 326.5 10
RJSONIO::toJSON(diamonds) 857.9 867.5 884.2 893.7 1022.2 10
jsonlite::toJSON(diamonds, dataframe = "column") 317.8 319.9 328.5 342.6 350.9 10
What if we throw some missing values in the mix:
diamonds2 <- diamonds
diamonds2[1,] <- NA;
microbenchmark(
rjson::toJSON(diamonds2),
RJSONIO::toJSON(diamonds2),
jsonlite::toJSON(diamonds2, dataframe = "column"),
times = 10
)
Unit: milliseconds
expr min lq median uq max neval
rjson::toJSON(diamonds2) 294.9 297.0 308.6 327.0 356.4 10
RJSONIO::toJSON(diamonds2) 1448.6 1476.2 1513.8 1578.2 1716.5 10
jsonlite::toJSON(diamonds2, dataframe = "column") 317.7 322.6 331.6 355.1 391.6 10
For parsing, comparing performance gets even trickier because rjson does not give any control over simplification. The following settings in RJSONIO and jsonlite are roughly equivalent to rjson:
json <- rjson::toJSON(diamonds)
microbenchmark(
rjson::fromJSON(json),
RJSONIO::fromJSON(json, simplifyWithNames=FALSE),
jsonlite::fromJSON(json, simplifyDataFrame = FALSE, simplifyMatrix = FALSE),
times = 10
)
Unit: milliseconds
expr min lq median uq max neval
rjson::fromJSON(json) 99.73 105.8 108.2 142.5 168.1 10
RJSONIO::fromJSON(json, simplifyWithNames = FALSE) 399.30 415.7 426.1 442.5 491.3 10
jsonlite::fromJSON(json, simplifyDataFrame = FALSE, simplifyMatrix = FALSE) 182.90 204.3 229.1 254.3 321.7 10