SteveG
SteveG

Reputation: 109

Importing, editing and saving JSON in a simple way?

I'm having problems with editing a JSON file and saving the results in a usable form.

My starting point is : modify-json-file-using-some-condition-and-create-new-json-file-in-r

In fact I want to do something even simpler and it still doesn't work! I'm using the jsonlite package.

An equivalent sample would look like this ...

$Apples
$Apples$Origin
$Apples$Origin$Id
[1] 2615

$Apples$Origin$season
[1] "Fall"

$Oranges
$Oranges$Origin
$Oranges$Origin$Id
[1] 2615

$Oranges$Origin$airportLabel
[1] "Orange airport"

$Oranges$Shipping
$Oranges$Shipping$ShipperId
[1] 123

$Oranges$Shipping$ShipperLabel
[1] "Brighter Orange"

I read the file, make some changes and save the resulting file back to HDD. Nothing simpler right?

json_list = read_json(path = "../documents/dummy.json")

json_list$Apples$Origin$Id = 1234
json_list$Oranges$Origin$Id = 4567
json_list$Oranges$Shipping$ShipperLabel = "Suntan Blue"

json_modified <- toJSON(json_list, pretty = TRUE)

write_json(json_modified, path = "../documents/dummy_new.json")

json_list appears as character format under the Rstudio file type column.
json_modified appears as json format under the Rstudio file type column.

Why this difference?

Now if I run the original file it works but the modified file fails. The JSON format checks out and I can't see any errors.

The real file is bigger than the example above but the method I've used is the same.

Am I doing something wrong in the way I edit or save the file?

I'm really new to JSON and this is really frustrating!

Any Ideas?

Thanks

Upvotes: 0

Views: 1359

Answers (1)

Greg
Greg

Reputation: 3326

In the absence of reproducible data, I can diagnose at least one potential problem.

Background

Within the jsonlite package, there exist functions that are mutual inverses:

Now this raw text (txt) might be

a JSON string, URL or file

As for jsonlite::read_json() and jsonlite::write_json(), they are also a pair of mutual inverses, which are like the former pair

except [that] they explicitly distinguish between path and literal input, and do not simplify by default.

That is, the latter are simply designed to handle file(path)s rather than strings of raw text.

So toJSON(fromJSON(txt = ...)) should return unchanged the text passed to txt, just as write_json(read_json(path = ...)) should write a file identical to that passed to path.

In short, toJSON() belongs with fromJSON(); while write_json() belongs with read_json().

The Problem

However, you have added a spurious step by mingling toJSON() with read_json() and write_json():

json_list = read_json(...)

# ...
json_modified <- toJSON(json_list, ...) # SPURIOUS STEP
# ...

write_json(json_modified, ...)

You see, write_json() already converts "to JSON", so toJSON() is wholly unnecessary. Indeed, toJSON() actually sabotages the process, since its textual return value is passed on (in json_modified) to write_json(), which expects (a structure of) R objects rather than text.

The Fix

Once you're done modifying json_list, just go straight to writing it:

json_list = read_json(path = "../documents/dummy.json")

json_list$Apples$Origin$Id = 1234
# Further modifications...

write_json(json_list, path = "../documents/dummy_new.json", pretty = TRUE)

Upvotes: 1

Related Questions