diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/docs/.nojekyll @@ -0,0 +1 @@ + diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 0000000..3ac120c --- /dev/null +++ b/docs/404.html @@ -0,0 +1,106 @@ + + + + + + + +Page not found (404) • jsonify + + + + + + + + + + + +
+
+ + + + +
+
+ + +Content not found. Please use links in the navbar. + +
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html new file mode 100644 index 0000000..c1da518 --- /dev/null +++ b/docs/LICENSE-text.html @@ -0,0 +1,82 @@ + +License • jsonify + + +
+
+ + + +
+
+ + +
YEAR: 2020
+COPYRIGHT HOLDER: David Cooley
+
+ +
+ + + +
+ + + +
+ + + + + + + + diff --git a/docs/LICENSE.html b/docs/LICENSE.html new file mode 100644 index 0000000..e84c995 --- /dev/null +++ b/docs/LICENSE.html @@ -0,0 +1,86 @@ + +MIT License • jsonify + + +
+
+ + + +
+
+ + +
+ +

Copyright (c) 2020 jsonify

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
+ +
+ + + +
+ + + +
+ + + + + + + + diff --git a/docs/articles/index.html b/docs/articles/index.html index 3067c7e..7f1d66e 100644 --- a/docs/articles/index.html +++ b/docs/articles/index.html @@ -1,55 +1,12 @@ - - - - - - - -Articles • jsonify - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Articles • jsonify - - - + + -
-
- -
-
+
+
jsonify
+
+
-
+ + + - - + diff --git a/docs/articles/jsonify.html b/docs/articles/jsonify.html index 91098c6..48c3a50 100644 --- a/docs/articles/jsonify.html +++ b/docs/articles/jsonify.html @@ -6,18 +6,21 @@ jsonify • jsonify - - - + + + + + - - + - + + +
@@ -61,258 +65,348 @@ +
-

There are two types of R objects we need to handle when converting to JSON, simple and complex.

+
+

To JSON +

+

There are two types of R objects we need to handle when converting to +JSON, simple and complex.

  1. Simple - scalars, vectors, matrices
  2. Complex - data.frames and lists
-

I’ve categorised them this way because ‘simple’ objects don’t include any form of recursion. That is, a vector can’t contain a data.frame or a list. But a list or data.frame can contain other data.frames, vectors, matrices, scalars, lists, and any combination thereof.

-
-

-Simple

-

Simple objects ( scalars, vectors and matrices ) get converted to JSON ARRAYS

- +

I’ve categorised them this way because ‘simple’ objects don’t include +any form of recursion. That is, a vector can’t contain a data.frame or a +list. But a list or data.frame can contain other data.frames, vectors, +matrices, scalars, lists, and any combination thereof.

+
+

Simple +

+

Simple objects ( scalars, vectors and matrices ) get converted to +JSON ARRAYS

+
+## scalar -> single array
+to_json( 1 )
+#  [1.0]
+to_json( "a" )
+#  ["a"]
+
+## scalar (unboxed) -> single value
+to_json( 1, unbox = TRUE )
+#  1.0
+to_json( "a", unbox = TRUE )
+#  "a"
+
+## vector -> array
+to_json( 1:4 )
+#  [1,2,3,4]
+to_json( letters[1:4] )
+#  ["a","b","c","d"]
+
+## named vector - array (of the elements)
+to_json( c("a" = 1, "b" = 2) )
+#  [1.0,2.0]
+
+## matrix -> array of arrays (by row)
+to_json( matrix(1:4, ncol = 2) )
+#  [[1,3],[2,4]]
+to_json( matrix(letters[1:4], ncol = 2))
+#  [["a","c"],["b","d"]]
+
+## matrix -> array of arrays (by column)
+to_json( matrix(1:4, ncol = 2), by = "column" )
+#  [[1,2],[3,4]]
+to_json( matrix(letters[1:4], ncol = 2 ), by = "column" )
+#  [["a","b"],["c","d"]]
-
-

-Complex - Lists

-

List of unnamed vectors gives an ARRAY of ARRAYS (since a vector gets converted to an array)

-
to_json( list( 1:2, c("a","b") )  )
-#  [[1,2],["a","b"]]
+
+

Complex - Lists +

+

List of unnamed vectors gives an ARRAY of ARRAYS (since a vector gets +converted to an array)

+
+to_json( list( 1:2, c("a","b") )  )
+#  [[1,2],["a","b"]]

A list with named elements gives an OBJECT with named ARRAYS

- +
+## List of vectors -> object with named arrays
+to_json( list( x = 1:2 ) )
+#  {"x":[1,2]}

A combination of named and unnamed list elements gives both

-
to_json( list( x = 1:2, y = list( letters[1:2] ) ) )
-#  {"x":[1,2],"y":[["a","b"]]}
+
+to_json( list( x = 1:2, y = list( letters[1:2] ) ) )
+#  {"x":[1,2],"y":[["a","b"]]}
-
-

-Complex - Data Frames

-

A data.frame will, by default, treat each row as an object (to maintain the relationship inherent in a row of data )

- -

You can set by = "column" to parse the data.frame by columns. And as each column (in this example) is a vector, each vector gets converted to an array. And since the vectors have names (the column names), we get an object of named arrays

-
## data.frame -> object of arrays (by column)
-to_json( data.frame( x = 1:2, y = 3:4), by = "column" )
-#  {"x":[1,2],"y":[3,4]}
-to_json( data.frame( x = c("a","b"), y = c("c","d") ), by = "column" )
-#  {"x":["a","b"],"y":["c","d"]}
+
+

Complex - Data Frames +

+

A data.frame will, by default, treat each row as an object (to +maintain the relationship inherent in a row of data )

+
+## data.frame -> array of objects (by row) 
+to_json( data.frame( x = 1:2, y = 3:4) )
+#  [{"x":1,"y":3},{"x":2,"y":4}]
+to_json( data.frame( x = c("a","b"), y = c("c","d")))
+#  [{"x":"a","y":"c"},{"x":"b","y":"d"}]
+

You can set by = "column" to parse the data.frame by +columns. And as each column (in this example) is a vector, each vector +gets converted to an array. And since the vectors have names (the column +names), we get an object of named arrays

+
+## data.frame -> object of arrays (by column)
+to_json( data.frame( x = 1:2, y = 3:4), by = "column" )
+#  {"x":[1,2],"y":[3,4]}
+to_json( data.frame( x = c("a","b"), y = c("c","d") ), by = "column" )
+#  {"x":["a","b"],"y":["c","d"]}
-
-

-Complex - Mixed objects

+
+

Complex - Mixed objects +

A data.frame where one columns is ‘AsIs’ a list

- -

The data.frame is being parsed ‘by row’, so we get an array of objects. The second column is a list of a named vector, so the val column contains an object of a named array.

+
+## data.frame where one colun is a list
+df <- data.frame( id = 1, val = I(list( x = 1:2 ) ) )
+to_json( df )
+#  [{"id":1.0,"val":{"x":[1,2]}}]
+

The data.frame is being parsed ‘by row’, so we get an array of +objects. The second column is a list of a named vector, so the +val column contains an object of a named array.

Here are the individual components to show how it’s put together

- -

If we take the same example and parse it ‘by column’ we get the id column treated as a vector, but the list column remains the same

- -

We can build up a more complex example with nested lists inside columns of data.frames

- +
+## which we see is made up of
+to_json( data.frame( id = 1 ) )
+#  [{"id":1.0}]
+## and
+to_json( list( x = 1:2 ) )
+#  {"x":[1,2]}
+

If we take the same example and parse it ‘by column’ we get the +id column treated as a vector, but the list column remains +the same

+
+to_json( df, by = "column" )
+#  {"id":[1.0],"val":{"x":[1,2]}}
+

We can build up a more complex example with nested lists inside +columns of data.frames

+
+
+df <- data.frame( id = 1, val = I(list(c(0,0))))
+df
+#    id  val
+#  1  1 0, 0
+to_json( df )
+#  [{"id":1.0,"val":[0.0,0.0]}]
+
+df <- data.frame( id = 1:2, val = I(list( x = 1:2, y = 3:4 ) ) )
+df
+#    id  val
+#  x  1 1, 2
+#  y  2 3, 4
+to_json( df )
+#  [{"id":1,"val":{"x":[1,2]}},{"id":2,"val":{"y":[3,4]}}]
+
+df <- data.frame( id = 1:2, val = I(list( x = 1:2, y = 3:6 ) ), val2 = I(list( a = "a", b = c("b","c") ) ) )
+df
+#    id        val val2
+#  x  1       1, 2    a
+#  y  2 3, 4, 5, 6 b, c
+pretty_json( df )
+#  [
+#      {
+#          "id": 1,
+#          "val": {
+#              "x": [
+#                  1,
+#                  2
+#              ]
+#          },
+#          "val2": {
+#              "a": [
+#                  "a"
+#              ]
+#          }
+#      },
+#      {
+#          "id": 2,
+#          "val": {
+#              "y": [
+#                  3,
+#                  4,
+#                  5,
+#                  6
+#              ]
+#          },
+#          "val2": {
+#              "b": [
+#                  "b",
+#                  "c"
+#              ]
+#          }
+#      }
+#  ]
+
+df <- data.frame( id = 1:2, val = I(list( x = 1:2, y = 3:6 ) ), val2 = I(list( a = "a", b = c("b","c") ) ), val3 = I(list( l = list( 1:3, l2 = c("a","b")), 1)) )
+df
+#    id        val val2         val3
+#  x  1       1, 2    a 1:3, c("....
+#  y  2 3, 4, 5, 6 b, c            1
+pretty_json( df )
+#  [
+#      {
+#          "id": 1,
+#          "val": {
+#              "x": [
+#                  1,
+#                  2
+#              ]
+#          },
+#          "val2": {
+#              "a": [
+#                  "a"
+#              ]
+#          },
+#          "val3": {
+#              "l": {
+#                  "": [
+#                      1,
+#                      2,
+#                      3
+#                  ],
+#                  "l2": [
+#                      "a",
+#                      "b"
+#                  ]
+#              }
+#          }
+#      },
+#      {
+#          "id": 2,
+#          "val": {
+#              "y": [
+#                  3,
+#                  4,
+#                  5,
+#                  6
+#              ]
+#          },
+#          "val2": {
+#              "b": [
+#                  "b",
+#                  "c"
+#              ]
+#          },
+#          "val3": {
+#              "": [
+#                  1.0
+#              ]
+#          }
+#      }
+#  ]
+
+
+
+

From JSON +

+

Use from_json() to convert from JSON to an R object.

+
+## scalar / vector
+js <- '[1,2,3]'
+from_json( js )
+#  [1] 1 2 3
+
+## matrix
+js <- '[[1,2],[3,4],[5,6]]'
+from_json( js )
+#       [,1] [,2]
+#  [1,]    1    2
+#  [2,]    3    4
+#  [3,]    5    6
+
+## data.frame
+js <- '[{"x":1,"y":"a"},{"x":2,"y":"b"}]'
+from_json( js )
+#    x y
+#  1 1 a
+#  2 2 b
+
+

Simplifying and NAs +

+

By default from_json() will try and simplify

+
    +
  • arrays to vectors
  • +
  • arrays of arrays to matrices
  • +
  • array of objects with consistent key-value pairs to data.frames
  • +
+

If an array contains objects with different keys, for example +'[{"x":1},{"y":2}]', from_json() will not +simplify this to a data.frame, because it would have to assume and +insert NAs in rows where data is missing.

+
+js <- '[{"x":1},{"y":2}]'
+from_json( js )
+#  [[1]]
+#  [[1]]$x
+#  [1] 1
+#  
+#  
+#  [[2]]
+#  [[2]]$y
+#  [1] 2
+

You can override this default and use fill_na = TRUE to +force it to a data.frame with NAs in place of missing +values

+
+js <- '[{"x":1},{"y":2}]'
+from_json( js, fill_na = TRUE )
+#     x  y
+#  1  1 NA
+#  2 NA  2
+
- +
-

Site built with pkgdown 1.3.0.

+

+

Site built with pkgdown 2.0.7.

+
+ + + diff --git a/docs/authors.html b/docs/authors.html index 288c887..b32b056 100644 --- a/docs/authors.html +++ b/docs/authors.html @@ -1,55 +1,12 @@ - - - - - - - -Authors • jsonify - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Authors and Citation • jsonify - + + - - - -
-
-
-
+
-
-
- + +
+ + + - - + diff --git a/docs/bootstrap-toc.css b/docs/bootstrap-toc.css new file mode 100644 index 0000000..5a85941 --- /dev/null +++ b/docs/bootstrap-toc.css @@ -0,0 +1,60 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ + +/* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ + +/* All levels of nav */ +nav[data-toggle='toc'] .nav > li > a { + display: block; + padding: 4px 20px; + font-size: 13px; + font-weight: 500; + color: #767676; +} +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 19px; + color: #563d7c; + text-decoration: none; + background-color: transparent; + border-left: 1px solid #563d7c; +} +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 18px; + font-weight: bold; + color: #563d7c; + background-color: transparent; + border-left: 2px solid #563d7c; +} + +/* Nav: second level (shown on .active) */ +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} +nav[data-toggle='toc'] .nav .nav > li > a { + padding-top: 1px; + padding-bottom: 1px; + padding-left: 30px; + font-size: 12px; + font-weight: normal; +} +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 29px; +} +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 28px; + font-weight: 500; +} + +/* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ +nav[data-toggle='toc'] .nav > .active > ul { + display: block; +} diff --git a/docs/bootstrap-toc.js b/docs/bootstrap-toc.js new file mode 100644 index 0000000..1cdd573 --- /dev/null +++ b/docs/bootstrap-toc.js @@ -0,0 +1,159 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ +(function() { + 'use strict'; + + window.Toc = { + helpers: { + // return all matching elements in the set, or their descendants + findOrFilter: function($el, selector) { + // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ + // http://stackoverflow.com/a/12731439/358804 + var $descendants = $el.find(selector); + return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); + }, + + generateUniqueIdBase: function(el) { + var text = $(el).text(); + var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); + return anchor || el.tagName.toLowerCase(); + }, + + generateUniqueId: function(el) { + var anchorBase = this.generateUniqueIdBase(el); + for (var i = 0; ; i++) { + var anchor = anchorBase; + if (i > 0) { + // add suffix + anchor += '-' + i; + } + // check if ID already exists + if (!document.getElementById(anchor)) { + return anchor; + } + } + }, + + generateAnchor: function(el) { + if (el.id) { + return el.id; + } else { + var anchor = this.generateUniqueId(el); + el.id = anchor; + return anchor; + } + }, + + createNavList: function() { + return $(''); + }, + + createChildNavList: function($parent) { + var $childList = this.createNavList(); + $parent.append($childList); + return $childList; + }, + + generateNavEl: function(anchor, text) { + var $a = $(''); + $a.attr('href', '#' + anchor); + $a.text(text); + var $li = $('
  • '); + $li.append($a); + return $li; + }, + + generateNavItem: function(headingEl) { + var anchor = this.generateAnchor(headingEl); + var $heading = $(headingEl); + var text = $heading.data('toc-text') || $heading.text(); + return this.generateNavEl(anchor, text); + }, + + // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). + getTopLevel: function($scope) { + for (var i = 1; i <= 6; i++) { + var $headings = this.findOrFilter($scope, 'h' + i); + if ($headings.length > 1) { + return i; + } + } + + return 1; + }, + + // returns the elements for the top level, and the next below it + getHeadings: function($scope, topLevel) { + var topSelector = 'h' + topLevel; + + var secondaryLevel = topLevel + 1; + var secondarySelector = 'h' + secondaryLevel; + + return this.findOrFilter($scope, topSelector + ',' + secondarySelector); + }, + + getNavLevel: function(el) { + return parseInt(el.tagName.charAt(1), 10); + }, + + populateNav: function($topContext, topLevel, $headings) { + var $context = $topContext; + var $prevNav; + + var helpers = this; + $headings.each(function(i, el) { + var $newNav = helpers.generateNavItem(el); + var navLevel = helpers.getNavLevel(el); + + // determine the proper $context + if (navLevel === topLevel) { + // use top level + $context = $topContext; + } else if ($prevNav && $context === $topContext) { + // create a new level of the tree and switch to it + $context = helpers.createChildNavList($prevNav); + } // else use the current $context + + $context.append($newNav); + + $prevNav = $newNav; + }); + }, + + parseOps: function(arg) { + var opts; + if (arg.jquery) { + opts = { + $nav: arg + }; + } else { + opts = arg; + } + opts.$scope = opts.$scope || $(document.body); + return opts; + } + }, + + // accepts a jQuery object, or an options object + init: function(opts) { + opts = this.helpers.parseOps(opts); + + // ensure that the data attribute is in place for styling + opts.$nav.attr('data-toggle', 'toc'); + + var $topContext = this.helpers.createChildNavList(opts.$nav); + var topLevel = this.helpers.getTopLevel(opts.$scope); + var $headings = this.helpers.getHeadings(opts.$scope, topLevel); + this.helpers.populateNav($topContext, topLevel, $headings); + } + }; + + $(function() { + $('nav[data-toggle="toc"]').each(function(i, el) { + var $nav = $(el); + Toc.init($nav); + }); + }); +})(); diff --git a/docs/index.html b/docs/index.html index 87158d3..92b61bb 100644 --- a/docs/index.html +++ b/docs/index.html @@ -5,21 +5,24 @@ -Converts 'R' Objects to Javascript Object Notation (JSON) • jsonify - - - - - - +Convert Between R Objects and Javascript Object Notation (JSON) • jsonify + + + + + + + - -
    + + + +
    -
    - +
    - - -

    CRAN_Status_Badge downloadsCRAN RStudio mirror downloads Travis build status Coverage status

    -
    - -

    jsonify converts R objects to JSON.

    -
    -

    -There are already JSON converters, why did you build this one?

    + +
    + +

    Converts between R objects and JSON.

    +
    +js <- '[{"x":1,"y":"a"},{"x":2,"y":"b"}]'
    +( df <- from_json( js ) )
    +#    x y
    +#  1 1 a
    +#  2 2 b
    +( to_json( df ) )
    +#  [{"x":1,"y":"a"},{"x":2,"y":"b"}]
    +
    +

    There are already JSON converters, why did you build this one? +

    Because I wanted it available at the source ( C++ ) level for integrating into other packages.

    -
    -

    -Is it fast?

    -

    yeah it’s pretty good.

    - +
    +

    What do you mean by “available at the source” ? +

    +

    I want to be able to call the C++ code from another package, without going to & from R. Therefore, the C++ code is implemented in headers, so you can “link to” it in your own package.

    +

    For example, the LinkingTo section in DESCRIPTION will look something like

    +
    LinkingTo: 
    +    Rcpp,
    +    rapidjsonr (>= 1.2.0),
    +    jsonify
    +

    And in a c++ source file you can #include the header and use the available functions

    +
    #include "jsonify/jsonify.hpp"
    +
    +Rcpp::StringVector my_json( Rcpp::DataFrame df ) {
    +  return jsonify::api::to_json( df );
    +}
    +

    You can see an example of this in my geojsonsf package

    +
    -
    -

    -I thought you had an example of it being MUCH quicker than jsonlite ?

    -

    Yeah, but I realised it was comparing two different methods. When jsonify was parsing nested lists, it was parsing data.frames column-wise, whereas jsonlite was row-wise. Which is a slower operation

    +
    +

    Can I call it from R if I want to? +

    +

    Yes. Just like the examples in this readme use to_json()

    +
    +df <- data.frame(
    +  id = 1:3
    +  , val = letters[1:3]
    +  )
    +jsonify::to_json( df )
    +#  [{"id":1,"val":"a"},{"id":2,"val":"b"},{"id":3,"val":"c"}]
    -
    -

    -Oh right. So it wasn’t a fair test then.

    -

    Correct.

    -

    Here’s a more suitable comparison

    - +
    +

    Is it fast? +

    +

    yeah it’s pretty good.

    +
    +
    +library(microbenchmark)
    +library(jsonlite)
    +
    +n <- 1e6
    +df <- data.frame(
    +  id = 1:n
    +  , value = sample(letters, size = n, replace = T)
    +  , val2 = rnorm(n = n)
    +  , log = sample(c(T,F), size = n, replace = T)
    +  , stringsAsFactors = FALSE
    +)
    +
    +microbenchmark(
    +  jsonlite = {
    +    jlt <- jsonlite::toJSON( df )
    +  },
    +  jsonify = {
    +    jfy <- jsonify::to_json( df )
    +  },
    +  times = 3
    +)
    +
    +# Unit: seconds
    +#      expr      min       lq     mean   median       uq      max neval
    +#  jsonlite 2.017081 2.063732 2.540350 2.110383 2.801984 3.493585     3
    +#   jsonify 1.186239 1.202719 1.514067 1.219198 1.677981 2.136763     3
    +
    +
    +microbenchmark(
    +  jsonlite = {
    +    df_jlt <- jsonlite::fromJSON( jlt )
    +  },
    +  jsonify = {
    +    df_jfy <- jsonify::from_json( jfy )
    +  },
    +  times = 3
    +)
    +
    +# Unit: seconds
    +#      expr      min       lq     mean   median       uq      max neval
    +#  jsonlite 5.034888 5.149688 5.229363 5.264489 5.326601 5.388713     3
    +#   jsonify 4.551434 4.629683 4.678198 4.707932 4.741579 4.775227     3
    +
    +n <- 1e4
    +x <- list(
    +  x = rnorm(n = n)
    +  , y = list(x = rnorm(n = n))
    +  , z = list( list( x = rnorm(n = n)))
    +  , xx = rnorm(n = n)
    +  , yy = data.frame(
    +      id = 1:n
    +      , value = sample(letters, size = n, replace = T)
    +      , val2 = rnorm(n = n)
    +      , log = sample(c(T,F), size = n, replace = T)
    +    )
    +)
    +
    +microbenchmark(
    +  jsonlite = {
    +    jlt <- jsonlite::toJSON( x )
    +  },
    +  jsonify = {
    +    jfy <- jsonify::to_json( x )
    +  },
    +  times = 5
    +)
    + 
    +# Unit: milliseconds
    +#      expr      min       lq     mean   median       uq      max neval
    +#  jsonlite 18.52028 18.82241 19.32112 18.99683 19.18103 21.08508     5
    +#   jsonify 17.72060 18.19092 19.58308 19.52457 21.14687 21.33241     5
    +   
    +
    +microbenchmark(
    +  jsonlite = {
    +    df_jlt <- jsonlite::fromJSON( jlt )
    +  },
    +  jsonify = {
    +    df_jfy <- jsonify::from_json( jfy )
    +  },
    +  times = 3
    +)
    +
    +# Unit: milliseconds
    +#      expr      min       lq     mean   median       uq      max neval
    +#  jsonlite 62.53554 62.96435 63.12574 63.39316 63.42084 63.44853     3
    +#   jsonify 42.47449 42.53826 43.38475 42.60204 43.83988 45.07773     3
    -
    -

    -There’s no Date type in JSON, how have you handled this?

    +
    +

    There’s no Date type in JSON, how have you handled this? +

    At its core Dates in R are numeric, so they are treated as numbers when converted to JSON. However, the user can coerce to character through the numeric_dates argument.

    -
    df <- data.frame(dte = as.Date("2018-01-01"))
    -jsonify::to_json( df )
    -#  [{"dte":17532.0}]
    -
    -df <- data.frame(dte = as.Date("2018-01-01"))
    -jsonify::to_json( df, numeric_dates = FALSE )
    -#  [{"dte":"2018-01-01"}]
    +
    +df <- data.frame(dte = as.Date("2018-01-01"))
    +jsonify::to_json( df )
    +#  [{"dte":17532.0}]
    +
    +df <- data.frame(dte = as.Date("2018-01-01"))
    +jsonify::to_json( df, numeric_dates = FALSE )
    +#  [{"dte":"2018-01-01"}]
    -
    -

    -And POSIXct and POSIXlt?

    +
    +

    And POSIXct and POSIXlt? +

    The same

    -
    
    -jsonify::to_json( as.POSIXct("2018-01-01 10:00:00") )
    -#  [1514761200.0]
    -jsonify::to_json( as.POSIXct("2018-01-01 10:00:00"), numeric_dates = FALSE)
    -#  ["2017-12-31T23:00:00"]
    +
    +
    +jsonify::to_json( as.POSIXct("2018-01-01 10:00:00") )
    +#  [1514761200.0]
    +jsonify::to_json( as.POSIXct("2018-01-01 10:00:00"), numeric_dates = FALSE)
    +#  ["2017-12-31T23:00:00"]

    However, here the POSIXct values are returned in UTC timezone. This is by design.

    POSIXlt will return each component of the date-time

    - -
    -
    -

    -What about lists?

    -

    The purpose of this library is speed. A lot of overhead is incurred iterating over a list to find and convert objects from one type to another.

    -

    For v0.2.0 I’ve managed to get the date handling at the c++ level, so there’s no penalty for recursing through the list to coerce to character.

    -

    Therefore, lists will work too

    - - -

    And it’s still fast because of the design choice to coerce dates to UTC. All the date handling is done at the C++ leve, not R. So it’s faster.

    - +
    +x <- as.POSIXlt("2018-01-01 01:00:00", tz = "GMT")
    +jsonify::to_json( x )
    +#  {"sec":[0.0],"min":[0],"hour":[1],"mday":[1],"mon":[0],"year":[118],"wday":[1],"yday":[0],"isdst":[0]}
    +
    +jsonify::to_json( x, numeric_dates = FALSE)
    +#  {"sec":[0.0],"min":[0],"hour":[1],"mday":[1],"mon":[0],"year":[118],"wday":[1],"yday":[0],"isdst":[0]}
    -
    -

    -That output looks nice, is that pretty_json() function new?

    -

    Yep, it’s a new feature in v0.2.0

    +
    +

    I see factors are converted to strings +

    +

    Yep. Even though I constructed a data.frame() without setting stringsAsFactros = FALSE, jsonify automatically treats factors as strings.

    -
    -

    -What do you mean by “available at the source” ?

    -

    I want to be able to call the C++ code from another package, without going to & from R. Therefore, the C++ code is implemented in headers, so you can “link to” it in your own package.

    -

    For example, the LinkingTo section in DESCRIPTION will look something like

    - -

    And in a c++ source file you can #include the header and use the available functions

    - -
    -
    -

    -Can I call it from R if I want to?

    -

    Yes. Just like the examples in this readme use to_json()

    - -
    -
    -

    -I see factors are converted to strings

    -

    Yep. Even though I constructed a data.frame() without setting stringsAsFactros = FALSE, jsonify automatically treats factors as strings.

    -
    -
    -

    -Has this changed from v0.1?

    +
    +

    Has this changed from v0.1? +

    Yes. And it’s to keep the data more inline with modern concepts and design patterns.

    If you want factors, use factors_as_string = FALSE in the to_json() call

    - +
    +jsonify::to_json( df, factors_as_string = FALSE )
    +#  [{"dte":17532.0}]
    -
    -

    -How do I install it?

    +
    +

    How do I install it? +

    Get the latest release version from CRAN

    -
    install.packages("jsonify")
    -

    Or the development version from GitHub with:

    - +
    +install.packages("jsonify")
    +

    Or the development version from GitHub with:

    +
    +# install.packages("devtools")
    +devtools::install_github("SymbolixAU/jsonify")
    +
    -
    -

    Site built with pkgdown 1.3.0.

    +

    +

    Site built with pkgdown 2.0.7.

    +
    + + + diff --git a/docs/news/index.html b/docs/news/index.html index 2738134..55662fb 100644 --- a/docs/news/index.html +++ b/docs/news/index.html @@ -1,55 +1,12 @@ - - - - - - - -Changelog • jsonify - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Changelog • jsonify - + + - - -
    -
    - -
    -
    +
    - +
    -
    - + +
    + + + - - + diff --git a/docs/pkgdown.css b/docs/pkgdown.css index c03fb08..80ea5b8 100644 --- a/docs/pkgdown.css +++ b/docs/pkgdown.css @@ -17,12 +17,14 @@ html, body { height: 100%; } +body { + position: relative; +} + body > .container { display: flex; height: 100%; flex-direction: column; - - padding-top: 60px; } body > .container .row { @@ -54,8 +56,10 @@ img.icon { float: right; } -img { +/* Ensure in-page images don't run outside their container */ +.contents img { max-width: 100%; + height: auto; } /* Fix bug in bootstrap (only seen in firefox) */ @@ -69,14 +73,17 @@ summary { margin-top: calc(-60px + 1em); } +dd { + margin-left: 3em; +} + /* Section anchors ---------------------------------*/ a.anchor { - margin-left: -30px; - display:inline-block; - width: 30px; - height: 30px; - visibility: hidden; + display: none; + margin-left: 5px; + width: 20px; + height: 20px; background-image: url(./link.svg); background-repeat: no-repeat; @@ -84,17 +91,15 @@ a.anchor { background-position: center center; } -.hasAnchor:hover a.anchor { - visibility: visible; -} - -@media (max-width: 767px) { - .hasAnchor:hover a.anchor { - visibility: hidden; - } +h1:hover .anchor, +h2:hover .anchor, +h3:hover .anchor, +h4:hover .anchor, +h5:hover .anchor, +h6:hover .anchor { + display: inline-block; } - /* Fixes for fixed navbar --------------------------*/ .contents h1, .contents h2, .contents h3, .contents h4 { @@ -102,37 +107,135 @@ a.anchor { margin-top: -40px; } -/* Static header placement on mobile devices */ -@media (max-width: 767px) { - .navbar-fixed-top { - position: absolute; - } - .navbar { - padding: 0; - } +/* Navbar submenu --------------------------*/ + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu>.dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover>.dropdown-menu { + display: block; +} + +.dropdown-submenu>a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #cccccc; + margin-top: 5px; + margin-right: -10px; +} + +.dropdown-submenu:hover>a:after { + border-left-color: #ffffff; } +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left>.dropdown-menu { + left: -100%; + margin-left: 10px; + border-radius: 6px 0 6px 6px; +} /* Sidebar --------------------------*/ -#sidebar { +#pkgdown-sidebar { margin-top: 30px; + position: -webkit-sticky; + position: sticky; + top: 70px; } -#sidebar h2 { + +#pkgdown-sidebar h2 { font-size: 1.5em; margin-top: 1em; } -#sidebar h2:first-child { +#pkgdown-sidebar h2:first-child { margin-top: 0; } -#sidebar .list-unstyled li { +#pkgdown-sidebar .list-unstyled li { margin-bottom: 0.5em; } +/* bootstrap-toc tweaks ------------------------------------------------------*/ + +/* All levels of nav */ + +nav[data-toggle='toc'] .nav > li > a { + padding: 4px 20px 4px 6px; + font-size: 1.5rem; + font-weight: 400; + color: inherit; +} + +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 5px; + color: inherit; + border-left: 1px solid #878787; +} + +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 5px; + font-size: 1.5rem; + font-weight: 400; + color: inherit; + border-left: 2px solid #878787; +} + +/* Nav: second level (shown on .active) */ + +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} + +nav[data-toggle='toc'] .nav .nav > li > a { + padding-left: 16px; + font-size: 1.35rem; +} + +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 15px; +} + +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 15px; + font-weight: 500; + font-size: 1.35rem; +} + +/* orcid ------------------------------------------------------------------- */ + .orcid { - height: 16px; + font-size: 16px; + color: #A6CE39; + /* margins are required by official ORCID trademark and display guidelines */ + margin-left:4px; + margin-right:4px; vertical-align: middle; } @@ -140,14 +243,14 @@ a.anchor { .ref-index th {font-weight: normal;} -.ref-index td {vertical-align: top;} +.ref-index td {vertical-align: top; min-width: 100px} .ref-index .icon {width: 40px;} .ref-index .alias {width: 40%;} .ref-index-icons .alias {width: calc(40% - 40px);} .ref-index .title {width: 60%;} .ref-arguments th {text-align: right; padding-right: 10px;} -.ref-arguments th, .ref-arguments td {vertical-align: top;} +.ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} .ref-arguments .name {width: 20%;} .ref-arguments .desc {width: 80%;} @@ -160,31 +263,26 @@ table { /* Syntax highlighting ---------------------------------------------------- */ -pre { - word-wrap: normal; - word-break: normal; - border: 1px solid #eee; -} - -pre, code { +pre, code, pre code { background-color: #f8f8f8; color: #333; } +pre, pre code { + white-space: pre-wrap; + word-break: break-all; + overflow-wrap: break-word; +} -pre code { - overflow: auto; - word-wrap: normal; - white-space: pre; +pre { + border: 1px solid #eee; } -pre .img { +pre .img, pre .r-plt { margin: 5px 0; } -pre .img img { +pre .img img, pre .r-plt img { background-color: #fff; - display: block; - height: auto; } code a, pre a { @@ -201,9 +299,8 @@ a.sourceLine:hover { .kw {color: #264D66;} /* keyword */ .co {color: #888888;} /* comment */ -.message { color: black; font-weight: bolder;} -.error { color: orange; font-weight: bolder;} -.warning { color: #6A0366; font-weight: bolder;} +.error {font-weight: bolder;} +.warning {font-weight: bolder;} /* Clipboard --------------------------*/ @@ -222,6 +319,19 @@ a.sourceLine:hover { visibility: visible; } +/* headroom.js ------------------------ */ + +.headroom { + will-change: transform; + transition: transform 200ms linear; +} +.headroom--pinned { + transform: translateY(0%); +} +.headroom--unpinned { + transform: translateY(-100%); +} + /* mark.js ----------------------------*/ mark { @@ -234,3 +344,41 @@ mark { .html-widget { margin-bottom: 10px; } + +/* fontawesome ------------------------ */ + +.fab { + font-family: "Font Awesome 5 Brands" !important; +} + +/* don't display links in code chunks when printing */ +/* source: https://stackoverflow.com/a/10781533 */ +@media print { + code a:link:after, code a:visited:after { + content: ""; + } +} + +/* Section anchors --------------------------------- + Added in pandoc 2.11: https://github.com/jgm/pandoc-templates/commit/9904bf71 +*/ + +div.csl-bib-body { } +div.csl-entry { + clear: both; +} +.hanging-indent div.csl-entry { + margin-left:2em; + text-indent:-2em; +} +div.csl-left-margin { + min-width:2em; + float:left; +} +div.csl-right-inline { + margin-left:2em; + padding-left:1em; +} +div.csl-indent { + margin-left: 2em; +} diff --git a/docs/pkgdown.js b/docs/pkgdown.js index eb7e83d..6f0eee4 100644 --- a/docs/pkgdown.js +++ b/docs/pkgdown.js @@ -2,18 +2,11 @@ (function($) { $(function() { - $("#sidebar") - .stick_in_parent({offset_top: 40}) - .on('sticky_kit:bottom', function(e) { - $(this).parent().css('position', 'static'); - }) - .on('sticky_kit:unbottom', function(e) { - $(this).parent().css('position', 'relative'); - }); + $('.navbar-fixed-top').headroom(); - $('body').scrollspy({ - target: '#sidebar', - offset: 60 + $('body').css('padding-top', $('.navbar').height() + 10); + $(window).resize(function(){ + $('body').css('padding-top', $('.navbar').height() + 10); }); $('[data-toggle="tooltip"]').tooltip(); @@ -87,7 +80,7 @@ $(document).ready(function() { var copyButton = ""; - $(".examples, div.sourceCode").addClass("hasCopyButton"); + $("div.sourceCode").addClass("hasCopyButton"); // Insert copy buttons: $(copyButton).prependTo(".hasCopyButton"); @@ -98,7 +91,7 @@ // Initialize clipboard: var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { text: function(trigger) { - return trigger.parentNode.textContent; + return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); } }); diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index 6a18080..619f050 100644 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -1,6 +1,7 @@ -pandoc: 2.3.1 -pkgdown: 1.3.0 +pandoc: 3.1.1 +pkgdown: 2.0.7 pkgdown_sha: ~ articles: jsonify: jsonify.html +last_built: 2024-01-17T21:33Z diff --git a/docs/reference/Rplot001.png b/docs/reference/Rplot001.png new file mode 100644 index 0000000..17a3580 Binary files /dev/null and b/docs/reference/Rplot001.png differ diff --git a/docs/reference/as.json.html b/docs/reference/as.json.html new file mode 100644 index 0000000..596a781 --- /dev/null +++ b/docs/reference/as.json.html @@ -0,0 +1,101 @@ + +Coerce string to JSON — as.json • jsonify + + +
    +
    + + + +
    +
    + + +
    +

    Coerce string to JSON

    +
    + +
    +
    as.json(x)
    +
    + +
    +

    Arguments

    +
    x
    +

    string to coerce to JSON

    + +
    + +
    +

    Examples

    +
    
    +js <- '{"x":1,"y":2}'
    +as.json(js)
    +#> {"x":1,"y":2} 
    +
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/from_json.html b/docs/reference/from_json.html new file mode 100644 index 0000000..5d183b6 --- /dev/null +++ b/docs/reference/from_json.html @@ -0,0 +1,239 @@ + +From JSON — from_json • jsonify + + +
    +
    + + + +
    +
    + + +
    +

    Converts JSON to an R object.

    +
    + +
    +
    from_json(json, simplify = TRUE, fill_na = FALSE, buffer_size = 1024)
    +
    + +
    +

    Arguments

    +
    json
    +

    JSON to convert to R object. Can be a string, url or link to a file.

    + + +
    simplify
    +

    logical, if TRUE, coerces JSON to the simplest R object possible. See Details

    + + +
    fill_na
    +

    logical, if TRUE and simplify is TRUE, +data.frames will be na-filled if there are missing JSON keys. +Ignored if simplify is FALSE. See details and examples.

    + + +
    buffer_size
    +

    size of buffer used when reading a file from disk. Defaults to 1024

    + +
    +
    +

    Details

    +

    When simplify = TRUE

    • single arrays are coerced to vectors

    • +
    • array of arrays (all the same length) are coerced to matrices

    • +
    • objects with the same keys are coerced to data.frames

    • +

    When simplify = TRUE and fill_na = TRUE

    • objects are coerced to data.frames, and any missing values are filled with NAs

    • +
    + +
    +

    Examples

    +
    
    +from_json('{"a":[1, 2, 3]}')
    +#> $a
    +#> [1] 1 2 3
    +#> 
    +from_json('{"a":8, "b":99.5, "c":true, "d":"cats", "e":[1, "cats", 3]}')
    +#> $a
    +#> [1] 8
    +#> 
    +#> $b
    +#> [1] 99.5
    +#> 
    +#> $c
    +#> [1] TRUE
    +#> 
    +#> $d
    +#> [1] "cats"
    +#> 
    +#> $e
    +#> [1] "1"    "cats" "3"   
    +#> 
    +from_json('{"a":8, "b":{"c":123, "d":{"e":456}}}')
    +#> $a
    +#> [1] 8
    +#> 
    +#> $b
    +#> $b$c
    +#> [1] 123
    +#> 
    +#> $b$d
    +#> $b$d$e
    +#> [1] 456
    +#> 
    +#> 
    +#> 
    +
    +lst <- list("a" = 5L, "b" = 1.43, "c" = "cats", "d" = FALSE)
    +js <- jsonify::to_json(lst, unbox = TRUE)
    +from_json( js )
    +#> $a
    +#> [1] 5
    +#> 
    +#> $b
    +#> [1] 1.43
    +#> 
    +#> $c
    +#> [1] "cats"
    +#> 
    +#> $d
    +#> [1] FALSE
    +#> 
    +
    +## Return a data frame
    +from_json('[{"id":1,"val":"a"},{"id":2,"val":"b"}]')
    +#>   id val
    +#> 1  1   a
    +#> 2  2   b
    +
    +## Return a data frame with a list column
    +from_json('[{"id":1,"val":"a"},{"id":2,"val":["b","c"]}]')
    +#>   id  val
    +#> 1  1    a
    +#> 2  2 b, c
    +
    +## Without simplifying to a data.frame
    +from_json('[{"id":1,"val":"a"},{"id":2,"val":["b","c"]}]', simplify = FALSE )
    +#> [[1]]
    +#> [[1]]$id
    +#> [1] 1
    +#> 
    +#> [[1]]$val
    +#> [1] "a"
    +#> 
    +#> 
    +#> [[2]]
    +#> [[2]]$id
    +#> [1] 2
    +#> 
    +#> [[2]]$val
    +#> [[2]]$val[[1]]
    +#> [1] "b"
    +#> 
    +#> [[2]]$val[[2]]
    +#> [1] "c"
    +#> 
    +#> 
    +#> 
    +
    +## Missing JSON keys 
    +from_json('[{"x":1},{"x":2,"y":"hello"}]')
    +#> [[1]]
    +#> [[1]]$x
    +#> [1] 1
    +#> 
    +#> 
    +#> [[2]]
    +#> [[2]]$x
    +#> [1] 2
    +#> 
    +#> [[2]]$y
    +#> [1] "hello"
    +#> 
    +#> 
    +
    +## Missing JSON keys - filling with NAs
    +from_json('[{"x":1},{"x":2,"y":"hello"}]', fill_na = TRUE )
    +#>   x     y
    +#> 1 1  <NA>
    +#> 2 2 hello
    +
    +## Duplicate object keys
    +from_json('[{"x":1,"x":"a"},{"x":2,"x":"b"}]')
    +#>   x
    +#> 1 1
    +#> 2 2
    +
    +from_json('[{"id":1,"val":"a","val":1},{"id":2,"val":"b"}]', fill_na = TRUE )
    +#>   id val
    +#> 1  1   a
    +#> 2  2   b
    +
    +
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/from_ndjson.html b/docs/reference/from_ndjson.html new file mode 100644 index 0000000..e8151c5 --- /dev/null +++ b/docs/reference/from_ndjson.html @@ -0,0 +1,117 @@ + +from ndjson — from_ndjson • jsonify + + +
    +
    + + + +
    +
    + + +
    +

    Converts ndjson into R objects

    +
    + +
    +
    from_ndjson(ndjson, simplify = TRUE, fill_na = FALSE)
    +
    + +
    +

    Arguments

    +
    ndjson
    +

    new-line delimited JSON to convert to R object. Can be a string, url or link to a file.

    + + +
    simplify
    +

    logical, if TRUE, coerces JSON to the simplest R object possible. See Details

    + + +
    fill_na
    +

    logical, if TRUE and simplify is TRUE, +data.frames will be na-filled if there are missing JSON keys. +Ignored if simplify is FALSE. See details and examples.

    + +
    + +
    +

    Examples

    +
    
    +js <- to_ndjson( data.frame( x = 1:5, y = 6:10 ) )
    +from_ndjson( js )
    +#>   x  y
    +#> 1 1  6
    +#> 2 2  7
    +#> 3 3  8
    +#> 4 4  9
    +#> 5 5 10
    +
    +
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/index.html b/docs/reference/index.html index 24c1c74..9406733 100644 --- a/docs/reference/index.html +++ b/docs/reference/index.html @@ -1,55 +1,12 @@ - - - - - - - -Function reference • jsonify - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Function reference • jsonify - + + - - -
    -
    - -
    -
    +
    - - - - - - - - - - -
    -

    All functions

    + - - - - + + + + + + - - - - - - - - - + + - - -
    +

    All functions

    +
    +

    as.json()

    +

    Coerce string to JSON

    +

    from_json()

    +

    From JSON

    +

    from_ndjson()

    +

    from ndjson

    minify_json()

    Minify Json

    +

    pretty_json()

    Pretty Json

    +

    to_json()

    To JSON

    +
    +

    to_ndjson()

    +

    To ndjson

    validate_json()

    validate JSON

    - +
    - +
    -
    - + +
    + + + - - + diff --git a/docs/reference/jsondf-package.html b/docs/reference/jsondf-package.html deleted file mode 100644 index c2c01f0..0000000 --- a/docs/reference/jsondf-package.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - -A short title line describing what the package does — jsondf-package • jsonify - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
    - - - -
    - -
    -
    - - -
    - -

    A more detailed description of what the package does. A length - of about one to five lines is recommended.

    - -
    - - -

    Details

    - -

    This section should provide a more detailed overview of how to use the - package, including the most important functions.

    - -

    References

    - -

    This optional section can contain literature or other references for - background information.

    - -

    See also

    - -

    Optional links to other man pages

    - - -

    Examples

    -
    # NOT RUN { - ## Optional simple examples of the most important functions - ## These can be in \dontrun{} and \donttest{} blocks. - -# } -
    -
    - -
    - -
    - - -
    -

    Site built with pkgdown 1.3.0.

    -
    -
    -
    - - - - - - diff --git a/docs/reference/minify_json.html b/docs/reference/minify_json.html index 43c8418..9056933 100644 --- a/docs/reference/minify_json.html +++ b/docs/reference/minify_json.html @@ -1,58 +1,12 @@ - - - - - - - -Minify Json — minify_json • jsonify - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Minify Json — minify_json • jsonify - - - + + -
    -
    - -
    -
    +
    -

    Removes indentiation from a JSON string

    -
    -
    minify_json(json, ...)
    - -

    Arguments

    - - - - - - - - - - -
    json

    string of JSON

    ...

    other argments passed to to_json

    - +
    +
    minify_json(json, ...)
    +
    -

    Examples

    -
    -df <- data.frame(id = 1:10, val = rnorm(10)) -js <- to_json( df ) -jsp <- pretty_json(js) -minify_json( jsp )
    #> [{"id":1,"val":-1.4000435167217549},{"id":2,"val":0.2553170548452597},{"id":3,"val":-2.437263611219531},{"id":4,"val":-0.005571286746160735},{"id":5,"val":0.6215527214152141},{"id":6,"val":1.1484116060260608},{"id":7,"val":-1.821817660976626},{"id":8,"val":-0.24732530207352436},{"id":9,"val":-0.24419960677838332},{"id":10,"val":-0.2827054488144648}]
    -
    -
    - +
    -
    - + +
    + + + - - + diff --git a/docs/reference/pretty_json.html b/docs/reference/pretty_json.html index 2b50153..54a767d 100644 --- a/docs/reference/pretty_json.html +++ b/docs/reference/pretty_json.html @@ -1,58 +1,12 @@ - - - - - - - -Pretty Json — pretty_json • jsonify - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Pretty Json — pretty_json • jsonify - - - + + -
    -
    - -
    -
    +
    -

    Adds indentiation to a JSON string

    -
    -
    pretty_json(json, ...)
    - -

    Arguments

    - - - - - - - - - - -
    json

    string of JSON

    ...

    other argments passed to to_json

    - - -

    Examples

    -
    -df <- data.frame(id = 1:10, val = rnorm(10)) -js <- to_json( df ) -pretty_json(js)
    #> [ -#> { -#> "id": 1, -#> "val": -0.5536993836887205 -#> }, -#> { -#> "id": 2, -#> "val": 0.628982042036008 -#> }, -#> { -#> "id": 3, -#> "val": 2.065024895359223 -#> }, -#> { -#> "id": 4, -#> "val": -1.6309894020822316 -#> }, -#> { -#> "id": 5, -#> "val": 0.5124269498518048 -#> }, -#> { -#> "id": 6, -#> "val": -1.863011492068328 -#> }, -#> { -#> "id": 7, -#> "val": -0.5220125147454544 -#> }, -#> { -#> "id": 8, -#> "val": -0.05260190995387954 -#> }, -#> { -#> "id": 9, -#> "val": 0.5429963426611403 -#> }, -#> { -#> "id": 10, -#> "val": -0.9140748272599284 -#> } -#> ]
    -## can also use directly on an R object -pretty_json( df )
    #> [ -#> { -#> "id": 1, -#> "val": -0.5536993836887205 -#> }, -#> { -#> "id": 2, -#> "val": 0.628982042036008 -#> }, -#> { -#> "id": 3, -#> "val": 2.065024895359223 -#> }, -#> { -#> "id": 4, -#> "val": -1.6309894020822316 -#> }, -#> { -#> "id": 5, -#> "val": 0.5124269498518048 -#> }, -#> { -#> "id": 6, -#> "val": -1.863011492068328 -#> }, -#> { -#> "id": 7, -#> "val": -0.5220125147454544 -#> }, -#> { -#> "id": 8, -#> "val": -0.05260190995387954 -#> }, -#> { -#> "id": 9, -#> "val": 0.5429963426611403 -#> }, -#> { -#> "id": 10, -#> "val": -0.9140748272599284 -#> } -#> ]
    -
    -
    - +
    -
    - + +
    + + + - - + diff --git a/docs/reference/to_json.html b/docs/reference/to_json.html index 76eacee..fea2f01 100644 --- a/docs/reference/to_json.html +++ b/docs/reference/to_json.html @@ -1,58 +1,12 @@ - - - - - - - -To JSON — to_json • jsonify - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -To JSON — to_json • jsonify - - - + + -
    -
    - -
    -
    +
    -

    Converts R objects to JSON

    -
    -
    to_json(x, unbox = FALSE, digits = NULL, numeric_dates = TRUE,
    -  factors_as_string = TRUE, by = "row")
    - -

    Arguments

    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    x

    object to convert to JSON

    unbox

    logical indicating if single-value arrays should be 'unboxed', -that is, not contained inside an array.

    digits

    integer specifying the number of decimal places to round numerics. -Default is NULL - no rounding

    numeric_dates

    logical indicating if dates should be treated as numerics. -Defaults to TRUE for speed. If FALSE, the dates will be coerced to character in UTC time zone

    factors_as_string

    logical indicating if factors should be treated as strings. Defaults to TRUE.

    by

    either "row" or "column" indicating if data.frames and matrices should be processed -row-wise or column-wise. Defaults to "row"

    - - -

    Examples

    -
    -to_json(1:3)
    #> [1,2,3]
    to_json(letters[1:3])
    #> ["a","b","c"]
    to_json(data.frame(x = 1:3, y = letters[1:3]))
    #> [{"x":1,"y":"a"},{"x":2,"y":"b"},{"x":3,"y":"c"}]
    to_json(list(x = 1:3, y = list(z = letters[1:3])))
    #> {"x":[1,2,3],"y":{"z":["a","b","c"]}}
    to_json(seq(as.Date("2018-01-01"), as.Date("2018-01-05"), length.out = 5))
    #> [17532,17533,17534,17535,17536]
    to_json(seq(as.Date("2018-01-01"), as.Date("2018-01-05"), length.out = 5), numeric_dates = FALSE)
    #> ["2018-01-01","2018-01-02","2018-01-03","2018-01-04","2018-01-05"]
    -psx <- seq( - as.POSIXct("2018-01-01", tz = "Australia/Melbourne"), - as.POSIXct("2018-02-01", tz = "Australia/Melbourne"), - length.out = 5 - ) -to_json(psx)
    #> [1514725200,1515394800,1516064400,1516734000,1517403600]
    to_json(psx, numeric_dates = FALSE)
    #> ["2017-12-31T13:00:00","2018-01-08T07:00:00","2018-01-16T01:00:00","2018-01-23T19:00:00","2018-01-31T13:00:00"]
    -## unbox single-value arrays -to_json(list(x = 1), unbox = TRUE)
    #> {"x":1.0}
    to_json(list(x = 1, y = c("a"), z = list(x = 2, y = c("b"))), unbox = TRUE)
    #> {"x":1.0,"y":"a","z":{"x":2.0,"y":"b"}}
    -## rounding numbers using the digits argument -to_json(1.23456789, digits = 2)
    #> [1.23]
    df <- data.frame(x = 1L:3L, y = rnorm(3), z = letters[1:3]) -to_json(df, digits = 0 )
    #> [{"x":1,"y":0.0,"z":"a"},{"x":2,"y":0.0,"z":"b"},{"x":3,"y":-1.0,"z":"c"}]
    -## keeping factors -to_json(df, digits = 2, factors_as_string = FALSE )
    #> [{"x":1,"y":0.47,"z":1},{"x":2,"y":0.36,"z":2},{"x":3,"y":-1.3,"z":3}]
    - -
    -
    - +
    -
    - + +
    + + + - - + diff --git a/docs/reference/to_ndjson.html b/docs/reference/to_ndjson.html new file mode 100644 index 0000000..78be0f5 --- /dev/null +++ b/docs/reference/to_ndjson.html @@ -0,0 +1,199 @@ + +To ndjson — to_ndjson • jsonify + + +
    +
    + + + +
    +
    + + +
    +

    Converts R objects to ndjson

    +
    + +
    +
    to_ndjson(
    +  x,
    +  unbox = FALSE,
    +  digits = NULL,
    +  numeric_dates = TRUE,
    +  factors_as_string = TRUE,
    +  by = "row"
    +)
    +
    + +
    +

    Arguments

    +
    x
    +

    object to convert to JSON

    + + +
    unbox
    +

    logical indicating if single-value arrays should be 'unboxed', +that is, not contained inside an array.

    + + +
    digits
    +

    integer specifying the number of decimal places to round numerics. +Default is NULL - no rounding

    + + +
    numeric_dates
    +

    logical indicating if dates should be treated as numerics. +Defaults to TRUE for speed. If FALSE, the dates will be coerced to character in UTC time zone

    + + +
    factors_as_string
    +

    logical indicating if factors should be treated as strings. Defaults to TRUE.

    + + +
    by
    +

    either "row" or "column" indicating if data.frames and matrices should be processed +row-wise or column-wise. Defaults to "row"

    + +
    +
    +

    Details

    +

    Lists are converted to ndjson non-recursively. That is, each of the objects +in the list at the top level are converted to a new-line JSON object. Any nested +sub-elements are then contained within that JSON object. See examples

    +
    + +
    +

    Examples

    +
    
    +to_ndjson( 1:5 )
    +#> [1,2,3,4,5]
    +to_ndjson( letters )
    +#> ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
    +
    +mat <- matrix(1:6, ncol = 2)
    +
    +to_ndjson( x = mat )
    +#> [1,4]
    +#> [2,5]
    +#> [3,6]
    +to_ndjson( x = mat, by = "col" )
    +#> [1,2,3]
    +#> [4,5,6]
    +
    +df <- data.frame(
    +  x = 1:5
    +  , y = letters[1:5]
    +  , z = as.Date(seq(18262, 18262 + 4, by = 1 ), origin = "1970-01-01" )
    +  )
    +
    +to_ndjson( x = df )
    +#> {"x":1,"y":"a","z":18262.0}
    +#> {"x":2,"y":"b","z":18263.0}
    +#> {"x":3,"y":"c","z":18264.0}
    +#> {"x":4,"y":"d","z":18265.0}
    +#> {"x":5,"y":"e","z":18266.0}
    +to_ndjson( x = df, numeric_dates = FALSE )
    +#> {"x":1,"y":"a","z":"2020-01-01"}
    +#> {"x":2,"y":"b","z":"2020-01-02"}
    +#> {"x":3,"y":"c","z":"2020-01-03"}
    +#> {"x":4,"y":"d","z":"2020-01-04"}
    +#> {"x":5,"y":"e","z":"2020-01-05"}
    +to_ndjson( x = df, factors_as_string = FALSE )
    +#> {"x":1,"y":"a","z":18262.0}
    +#> {"x":2,"y":"b","z":18263.0}
    +#> {"x":3,"y":"c","z":18264.0}
    +#> {"x":4,"y":"d","z":18265.0}
    +#> {"x":5,"y":"e","z":18266.0}
    +to_ndjson( x = df, by = "column" )
    +#> {"x":[1,2,3,4,5]}
    +#> {"y":["a","b","c","d","e"]}
    +#> {"z":[18262.0,18263.0,18264.0,18265.0,18266.0]}
    +to_ndjson( x = df, by = "column", numeric_dates = FALSE )
    +#> {"x":[1,2,3,4,5]}
    +#> {"y":["a","b","c","d","e"]}
    +#> {"z":["2020-01-01","2020-01-02","2020-01-03","2020-01-04","2020-01-05"]}
    +
    +## Lists are non-recurisve; only elements `x` and `y` are converted to ndjson
    +lst <- list(
    +  x = 1:5
    +  , y = list(
    +    a = letters[1:5]
    +    , b = data.frame(i = 10:15, j = 20:25)
    +  )
    +)
    + 
    +to_ndjson( x = lst )
    +#> {"x":[1,2,3,4,5]}
    +#> {"y":{"a":["a","b","c","d","e"],"b":[{"i":10,"j":20},{"i":11,"j":21},{"i":12,"j":22},{"i":13,"j":23},{"i":14,"j":24},{"i":15,"j":25}]}}
    +to_ndjson( x = lst, by = "column")
    +#> {"x":[1,2,3,4,5]}
    +#> {"y":{"a":["a","b","c","d","e"],"b":{"i":[10,11,12,13,14,15],"j":[20,21,22,23,24,25]}}}
    +
    +
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/validate_json.html b/docs/reference/validate_json.html index 8d3e6d5..7a31dfa 100644 --- a/docs/reference/validate_json.html +++ b/docs/reference/validate_json.html @@ -1,58 +1,12 @@ - - - - - - - -validate JSON — validate_json • jsonify - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -validate JSON — validate_json • jsonify - - - + + -
    -
    - -
    -
    +
    -

    Validates JSON

    -
    -
    validate_json(json)
    - -

    Arguments

    - - - - - - -
    json

    character or json object

    - -

    Value

    +
    +
    validate_json(json)
    +
    -

    logical vector

    +
    +

    Arguments

    +
    json
    +

    character or json object

    + +
    +
    +

    Value

    -

    Examples

    -
    -validate_json('[]')
    #> [1] TRUE
    df <- data.frame(id = 1:5, val = letters[1:5]) -validate_json( to_json(df) )
    #> [1] TRUE
    -validate_json('{"x":1,"y":2,"z":"a"}')
    #> [1] TRUE
    -validate_json( c('{"x":1,"y":2,"z":"a"}', to_json(df) ) )
    #> [1] TRUE TRUE
    validate_json( c('{"x":1,"y":2,"z":a}', to_json(df) ) )
    #> [1] FALSE TRUE
    -
    -
    - +
    +

    Examples

    +
    
    +validate_json('[]')
    +#> [1] TRUE
    +df <- data.frame(id = 1:5, val = letters[1:5])
    +validate_json( to_json(df) )
    +#> [1] TRUE
    +
    +validate_json('{"x":1,"y":2,"z":"a"}')
    +#> [1] TRUE
    +
    +validate_json( c('{"x":1,"y":2,"z":"a"}', to_json(df) ) )
    +#> [1] TRUE TRUE
    +validate_json( c('{"x":1,"y":2,"z":a}', to_json(df) ) )
    +#> [1] FALSE  TRUE
    +
    +
    +
    +
    -
    - + +
    + + + - - + diff --git a/docs/sitemap.xml b/docs/sitemap.xml new file mode 100644 index 0000000..af36988 --- /dev/null +++ b/docs/sitemap.xml @@ -0,0 +1,54 @@ + + + + /404.html + + + /LICENSE-text.html + + + /LICENSE.html + + + /articles/index.html + + + /articles/jsonify.html + + + /authors.html + + + /index.html + + + /news/index.html + + + /reference/as.json.html + + + /reference/from_json.html + + + /reference/from_ndjson.html + + + /reference/index.html + + + /reference/minify_json.html + + + /reference/pretty_json.html + + + /reference/to_json.html + + + /reference/to_ndjson.html + + + /reference/validate_json.html + +