Getting started with JSON

library(tidyverse)
## ── Attaching packages ───────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.1     ✓ purrr   0.3.4
## ✓ tibble  3.0.3     ✓ dplyr   1.0.2
## ✓ tidyr   1.1.0     ✓ stringr 1.4.0
## ✓ readr   1.3.1     ✓ forcats 0.5.0
## ── Conflicts ──────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(jsonlite)
## 
## Attaching package: 'jsonlite'
## The following object is masked from 'package:purrr':
## 
##     flatten

JavaScript Object Notation (JSON) is an open-standard file format or data interchange format that uses human-readable text to transmit data objects consisting of attribute–value pairs and array data types.

{
  "firstName": "John",
  "lastName": "Smith",
  "isAlive": true,
  "age": 27,
  "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    },
    {
      "type": "mobile",
      "number": "123 456-7890"
    }
  ],
  "children": [],
  "spouse": null
}

In JSON, values must be one of the following data types:

Parsing JSON

txt <- '[12, 3, 7]'
x <- fromJSON(txt)
x
## [1] 12  3  7
txt <- '{"apple": 1, "banana": 2}'
x <- fromJSON(txt)
x
## $apple
## [1] 1
## 
## $banana
## [1] 2
# from file
example <- fromJSON("example.json")
# from the web
hello <- fromJSON("https://www.example.com/hello.json")

Simplification

Simplification is the process where JSON arrays automatically get converted from a list into a more specific R class. The fromJSON function has 3 arguments which control the simplification process: simplifyVector, simplifyDataFrame and simplifyMatrix. Each one is enabled by default.

JSON structure Example JSON data Simplifies to R class Argument in fromJSON
Array of primitives ["Amsterdam", "Rotterdam", "Utrecht", "Den Haag"] Atomic Vector simplifyVector
Array of objects [{"name":"Erik", "age":43}, {"name":"Anna", "age":32}] Data Frame simplifyDataFrame
Array of arrays [ [1, 2, 3], [4, 5, 6] ] Matrix simplifyMatrix

Atomic Vectors

When simplifyVector is enabled, JSON arrays containing primitives (strings, numbers, booleans or null) simplify into an atomic vector:

# A JSON array of primitives
json <- '["Mario", "Peach", null, "Bowser"]'
# Simplifies into an atomic vector
fromJSON(json)
## [1] "Mario"  "Peach"  NA       "Bowser"

Without simplification, any JSON array turns into a list:

# No simplification:
fromJSON(json, simplifyVector = FALSE)
## [[1]]
## [1] "Mario"
## 
## [[2]]
## [1] "Peach"
## 
## [[3]]
## NULL
## 
## [[4]]
## [1] "Bowser"

Data Frames

When simplifyDataFrame is enabled, JSON arrays containing objects (key-value pairs) simplify into a data frame:

json <-
'[
  {"Name" : "Mario", "Age" : 32, "Occupation" : "Plumber"}, 
  {"Name" : "Peach", "Age" : 21, "Occupation" : "Princess"},
  {},
  {"Name" : "Bowser", "Occupation" : "Koopa"}
]'
mydf <- fromJSON(json)
mydf
##     Name Age Occupation
## 1  Mario  32    Plumber
## 2  Peach  21   Princess
## 3   <NA>  NA       <NA>
## 4 Bowser  NA      Koopa

The data frame gets converted back into the original JSON structure by toJSON (whitespace and line breaks are ignorable in JSON).

mydf$Ranking <- c(3, 1, 2, 4)
 cat(toJSON(mydf, pretty = TRUE), file = "example2.json")

Hence you can go back and forth between dataframes and JSON, without any manual data restructuring.

Matrices and Arrays

When simplifyMatrix is enabled, JSON arrays containing equal-length sub-arrays simplify into a matrix (or higher order R array):

json <- '[
  [1, 2, 3, 4],
  [5, 6, 7, 8],
  [9, 10, 11, 12]
]'
mymatrix <- fromJSON(json)
mymatrix
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    5    6    7    8
## [3,]    9   10   11   12

Again, we can use toJSON to convert the matrix or array back into the original JSON structure:

toJSON(mymatrix, pretty = TRUE)
## [
##   [1, 2, 3, 4],
##   [5, 6, 7, 8],
##   [9, 10, 11, 12]
## ]
fromJSON(json, simplifyMatrix = FALSE)
## [[1]]
## [1] 1 2 3 4
## 
## [[2]]
## [1] 5 6 7 8
## 
## [[3]]
## [1]  9 10 11 12

Reference

jsonlite quick start: https://cran.r-project.org/web/packages/jsonlite/vignettes/json-aaquickstart.html jsonlite apis: https://cran.r-project.org/web/packages/jsonlite/vignettes/json-apis.html