Overview

This vignette:

  • introduces the opts argument for writing JSON with the write_json_X() family of functions.
  • outlines the creation of default options with opts_write_json()
  • provides extended examples of how these options control writing JSON

The opts argument - Specifying options when reading JSON

All write_json_x() functions have an opts argument. opts takes a named list of options used to configure the way yyjsonr writes JSON from R objects.

The default argument for opts is an empty list, which internally sets the default options for writing.

The default options for writing JSON can also be viewed by running opts_write_json().

The following three function calls are all equivalent ways of calling write_json_str() using the default options:

write_json_str(iris)
write_json_str(iris, opts = list())
write_json_str(iris, opts = opts_write_json())

Setting arguments to override the default options

Setting a single option (and keeping all other options at their default value) can be done in a number of ways.

The following three function calls are all equivalent:

write_json_str(iris, opts = list(str_specials = 'string'))
write_json_str(iris, opts = opts_write_json(str_specials = 'string'))
write_json_str(iris, str_specials = 'string')

Option digits - Number of decimal places for numeric values

The digits option controls the number of decimal places output for numeric values. The default value of digits = -1 indicates that the internal yyjson C library formatting should be used.

robj <- c(1, 1.23, 3.141592654)
write_json_str(robj)
#> [1] "[1.0,1.23,3.141592654]"
write_json_str(robj, digits = 2)
#> [1] "[1.0,1.23,3.14]"
write_json_str(robj, digits = 0)
#> [1] "[1,1,3]"

Option pretty - Use whitespace to make the JSON pretty

The pretty option is a logical value indicating whether or not whitespace should be used to make the resulting JSON more readable.

robj <- head(iris, 2)
write_json_str(robj) |> cat()
#> [{"Sepal.Length":5.1,"Sepal.Width":3.5,"Petal.Length":1.4,"Petal.Width":0.2,"Species":"setosa"},{"Sepal.Length":4.9,"Sepal.Width":3.0,"Petal.Length":1.4,"Petal.Width":0.2,"Species":"setosa"}]
write_json_str(robj, pretty = TRUE) |> cat()
#> [
#>   {
#>     "Sepal.Length": 5.1,
#>     "Sepal.Width": 3.5,
#>     "Petal.Length": 1.4,
#>     "Petal.Width": 0.2,
#>     "Species": "setosa"
#>   },
#>   {
#>     "Sepal.Length": 4.9,
#>     "Sepal.Width": 3.0,
#>     "Petal.Length": 1.4,
#>     "Petal.Width": 0.2,
#>     "Species": "setosa"
#>   }
#> ]

Option auto_unbox - Handling for R vectors of length 1

The auto_unbox option is a logical value indicating whether single values should be written as JSON scalars or JSON arrays (with length 1).

When auto_unbox = FALSE (the default), single values are always written as a JSON array i.e. within [] brackets.

When auto_unbox = TRUE, single values are written as bare JSON scalar values

robj <- list(1, c(1, 2), NA)
write_json_str(robj) |> cat()
#> [[1.0],[1.0,2.0],[null]]
write_json_str(robj, auto_unbox = TRUE) |> cat()
#> [1.0,[1.0,2.0],null]

Option dataframe - Orientation of data.frame output

The dataframe option controls the orientation of the data output to JSON:

  • dataframe = "rows" (the default) writes the data one-row-at-a-time as a JSON [] array containing a JSON {} object for each row.
  • dataframe = "cols" writes the data one-column-at-a-time as a JSON {} object containing JSON [] arrays.
robj <- head(iris, 3)
write_json_str(robj, pretty = TRUE) |> cat()
#> [
#>   {
#>     "Sepal.Length": 5.1,
#>     "Sepal.Width": 3.5,
#>     "Petal.Length": 1.4,
#>     "Petal.Width": 0.2,
#>     "Species": "setosa"
#>   },
#>   {
#>     "Sepal.Length": 4.9,
#>     "Sepal.Width": 3.0,
#>     "Petal.Length": 1.4,
#>     "Petal.Width": 0.2,
#>     "Species": "setosa"
#>   },
#>   {
#>     "Sepal.Length": 4.7,
#>     "Sepal.Width": 3.2,
#>     "Petal.Length": 1.3,
#>     "Petal.Width": 0.2,
#>     "Species": "setosa"
#>   }
#> ]
write_json_str(robj, pretty = TRUE, dataframe = "cols") |> cat()
#> {
#>   "Sepal.Length": [
#>     5.1,
#>     4.9,
#>     4.7
#>   ],
#>   "Sepal.Width": [
#>     3.5,
#>     3.0,
#>     3.2
#>   ],
#>   "Petal.Length": [
#>     1.4,
#>     1.4,
#>     1.3
#>   ],
#>   "Petal.Width": [
#>     0.2,
#>     0.2,
#>     0.2
#>   ],
#>   "Species": [
#>     "setosa",
#>     "setosa",
#>     "setosa"
#>   ]
#> }

Option factor - factor representation

The factor option indicates whether factors should be output as string (the default) or integer values.

robj <- sample(iris$Species, 10)
write_json_str(robj) |> cat()
#> ["versicolor","virginica","setosa","setosa","versicolor","versicolor","setosa","virginica","versicolor","setosa"]
write_json_str(robj, factor = 'integer') |> cat()
#> [2,3,1,1,2,2,1,3,2,1]

Option name_repair - Dealing with missing names in lists

When writing R lists which are only partially named, name_repair controls the names which are generated for the JSON output.

  • name_repair = "none" (the default) means that no names are created, and an empty string will be used as the key.
  • name_repair = "minimal" will generate default names for each unnamed list item based upon its position in the list.
robj <- list(a = 1, b = 2, 67)
write_json_str(robj, pretty = TRUE) |> cat()
#> {
#>   "a": [
#>     1.0
#>   ],
#>   "b": [
#>     2.0
#>   ],
#>   "": [
#>     67.0
#>   ]
#> }
write_json_str(robj, pretty = TRUE, name_repair = 'minimal') |> cat()
#> {
#>   "a": [
#>     1.0
#>   ],
#>   "b": [
#>     2.0
#>   ],
#>   "3": [
#>     67.0
#>   ]
#> }

Option num_specials - Writing numeric NA, NaN and Inf

JSON only has a single null value as a representation of missing-ness or special-ness of a value. That is, it has no natural representations to distinguish the special R numeric values like NA, NaN and Inf.

The num_specials option configures handling of these values in the JSON output:

  • num_specials = "null" (the default) will write special numeric values as JSON null values.
  • num_specials = "string" will write string representations of these values.
robj <- c(1.23, NA_real_, NaN, Inf, -Inf)
write_json_str(robj) |> cat()
#> [1.23,null,null,null,null]
write_json_str(robj, num_specials = 'string') |> cat()
#> [1.23,"NA","NaN","Inf","-Inf"]

Option str_specials - Writing character NA

JSON only has a single null value as a representation of missing-ness or special-ness of a value. That is, it has no specific representation of NA_character_.

The str_specials option configures handling of NA_character_ values in the JSON output:

  • str_specials = "null" (the default) will write NA_character_ as JSON null.
  • str_specials = "string" will write NA_character_ as "NA".
robj <- c("hello", NA_character_)
write_json_str(robj) |> cat()
#> ["hello",null]
write_json_str(robj, str_specials = 'string') |> cat()
#> ["hello","NA"]

Option yyjson_write_flag - internal YYJSON C library options

The yyjson C library supports a number of internal options for writing JSON.

These options are considered advanced, and the user is referred to the yyjson documentation for further explanation on what they control.

Warning: some of these advanced options do not make sense for interfacing with R, or otherwise conflict with how this package converts R objects to JSON.

# A reference list of all the possible YYJSON options
yyjsonr::yyjson_write_flag
#> $YYJSON_WRITE_NOFLAG
#> [1] 0
#> 
#> $YYJSON_WRITE_PRETTY
#> [1] 1
#> 
#> $YYJSON_WRITE_ESCAPE_UNICODE
#> [1] 2
#> 
#> $YYJSON_WRITE_ESCAPE_SLASHES
#> [1] 4
#> 
#> $YYJSON_WRITE_ALLOW_INF_AND_NAN
#> [1] 8
#> 
#> $YYJSON_WRITE_INF_AND_NAN_AS_NULL
#> [1] 16
#> 
#> $YYJSON_WRITE_ALLOW_INVALID_UNICODE
#> [1] 32
#> 
#> $YYJSON_WRITE_PRETTY_TWO_SPACES
#> [1] 64
#> 
#> $YYJSON_WRITE_NEWLINE_AT_END
#> [1] 128
write_json_str(
  c('hello / there', '#RStats'),
  opts = opts_write_json(yyjson_write_flag = c(
    yyjson_write_flag$YYJSON_WRITE_ESCAPE_SLASHES
  ))
) |> cat()
#> ["hello \/ there","#RStats"]