Christophe Christophe - 6 days ago 7
JSON Question

get wrong result by converting json string containing large number by using jsonlite

Here is the MWE, how to get the correct number as character.

require(jsonlite)

j <- "{\"id\": 323907258301939713}"
a <- fromJSON(j)

print(a$id, digits = 20)
class(a$id)

a$id <- as.character(a$id)
a$id
class(a$id)


Here is the output.

Loading required package: jsonlite
Loading required package: methods
[1] 323907258301939712
[1] "numeric"
[1] "323907258301939712"
[1] "character"


I want to get the exact number
323907258301939713
as character in
a

Answer

In JavaScript, numbers are double precision floating point, even when they look like integers, so they only have about 16 decimal digits of precision. In particular, the JavaScript code:

console.log(12345678901234567 == 12345678901234568)

prints "true".

The JSON standard inherits this limitation from JavaScript, so jsonlite is actually correctly interpreting your JSON by reading the number as a double.

Because this is actually a limitation of the JSON standard, if you have control over the program generating the JSON, you will save yourself pain and heartache down the road if you fix your JSON (for example, by representing the id attribute as a string):

{ "id": "323907258301939713" }

But, if you absolutely must parse this badly formed JSON, then you're in luck. The fromJSON function takes an undocumented boolean argument bigint_as_char which reads these large numbers into R as character values:

>     a <- fromJSON(j, bigint_as_char=TRUE)
>     print(a$id)
[1] "323907258301939713"
> 

However, you must be prepared to handle both plain numbers and character values in the rest of your R code, since fromJSON will still read small integers as normal numbers and only read these too-big integers as strings.

Comments