R Jsonlite - How to iterate a JSON list of objects? - r

I'm very new in R, but I was tasked with reading a JSON file that looks like the following :
{
"revisions" : [
{"number": 1, "description" : "first revision"},
{"number": 2, "description" : "second revision"},
{"number": 3, "description" : "third revision"}
]
}
I need to do some data manipulation iterating over revisions, but I can't understand what type of data structure jsonlite is transforming this list into, it seems it transposed it.
This is what I've tried :
json = fromJSON('data.json')
for (revision in json$revisions) {
print(revision$number) # Doesn't work
print(revision['number']) # Doesn't work
}
How can I read the json file in the way I'm trying above?
Using R 3.6.1, ideally I need to keep it to the base functions

json$revisions is a data.frame so you can try something like
for (i in seq(nrow(json$revisions))) {
print(json$revisions$number[i])
}

Related

Reading in JSON files in R with unicode strings

I have a txt file, that contains a list of json objects, with 1 of the keys containing an emoji representation in JavaCode format.
I want to parse the json file and convert it to CSV, with the column called emoji, and the emoji to be kept in its JavaCode representation for eg. "\uD83D\uDEB6\u200D\u2642\uFE0F".
Is there any way to do that? Currently, I'm using jsonlite to read it in but it seems to auto-convert the emoji data to be like this (which I assume is its Unicode representation): "<U+0001F6B6><U+200D><U+2640><U+FE0F>"
This is the code to read it in:
df <- fromJSON(data_file)
head(df)
Edited the question to include a sample json object from the list:
{
"x": [
{
"y": "a",
"emoji": "\uD83D\uDEB6\u200D\u2642\uFE0F"
}
],
"z": "b"
}

Error in fromJSON("employee.json") : not all data was parsed (0 chars were parsed out of a total of 13 chars)

I was trying to read the JSON file from my r studio as a purpose of learning how to read JSON file, but suddenly i got an parsing error.
employee.json
{
"id" : ["1","2","3","4","5","6","7","8" ],
"name" : ["Shubham","Nishka","Gunjan","Sumit","Arpita","Vaishali","Anisha","Ginni" ],
"salary" : ["623","552","669","825","762","882","783","964"],
"start_date" : [ "1/1/2012","9/15/2013","11/23/2013","5/11/2014","3/27/2015","5/21/2013","7/30/2013","6/17/2014"],
"dept" : [ "IT","Operations","Finance","HR","Finance","IT","Operations","Finance"]
}
.R file
library(rjson)
emp = fromJSON("employee.json")
e = as.data.frame(emp)
print(e)
The first argument to rjson::fromJSON is a JSON string. So your code is interpreting "employee.json" (note it has 13 characters) as JSON.
If you have saved a file named employee.json, you need to specify file = :
emp <- rjson::fromJSON(file = "employee.json")
This is not an issue when using jsonlite::fromJSON because the first argument can be a string, file or URL.

Is there a way in R to add comma's to incorrect JSON format?

I'm trying to work with a JSON file in R, but unfortunately the JSON file is unreadable by jsonlite in its current state. It's missing commas between the objects(arrays elements?). My objective is to form a data frame from this almost-JSON file. Example JSON file, code, and result below.
[
{"Source":"ADSB","Id":43061,"FlightId":"N668XX","Latitude":44.000083,"Longitude":-96.654788,"Alt":4450}
{"Source":"ADSB","Id":43062,"FlightId":"N683XX","Latitude":44.000083,"Longitude":-96.654788,"Alt":4450}
{"Source":"ADSB","Id":43063,"FlightId":"N652XX","Latitude":44.000083,"Longitude":-96.654788,"Alt":4450}
]
> jsondata = fromJSON("asdf.json")
Error in parse_con(txt, bigint_as_char) :
parse error: after array element, I expect ',' or ']'
"Heading":280,"Speed":124} {"Source":"ADSB","Id":43062,"Fl
(right here) ------^
After inserting comma's between the objects in the JSON file, it works no problem.
[
{"Source":"ADSB","Id":43061,"FlightId":"N668XX","Latitude":44.000083,"Longitude":-96.654788,"Alt":4450},
{"Source":"ADSB","Id":43062,"FlightId":"N683XX","Latitude":44.000083,"Longitude":-96.654788,"Alt":4450},
{"Source":"ADSB","Id":43063,"FlightId":"N652XX","Latitude":44.000083,"Longitude":-96.654788,"Alt":4450},
]
> jsondata = fromJSON("asdf.json")
> names(jsondata)
[1] "Source" "Id" "FlightId" "Latitude" "Longitude" "Alt"
How do I insert commas throughout this JSON file between all of the curvy brackets? (i.e. "}{" --> "},{"
Or is there another way for R to read my incomplete JSON file?
I'm less than a novice, so any help is much appreciated, thanks!!

Passing JSON from NodeJS to R using r-script

I am trying to setup a simple connect between a NodeJS application and an R-script.
So far I've managed to set up the basic connection and the running of the cript, by using r-script (found on npm).
However, I am not able to pass a simple json to the R so that it can be converted to a dataframe using jsonlite.
NodeJS Code:
var R = require("r-script");
var out = R("script.R")
.data({"Name" : "Mario", "Age" : 32, "Occupation" : "Plumber"}, {"Name" : "Peach", "Age" : 21, "Occupation" : "Princess"}, {}, {"Name" : "Bowser", "Occupation" : "Koopa"})
.callSync();
console.log(out);
script.R:
library("jsonlite")
mydf <- fromJSON(input[[1]])
This gives the output:
'Argument 'txt' must be a JSON string, URL or file.'
I have tried removing the indexation of the vector (and give the full list to the fromJSON) but it also doesn't work.
Has anyone sucessfully passed JSON to an R script with this npm module?
Thanks in advance!
EDIT:
Also, if place the JSON between "'", it gives me "trailing errors" in spaces, and if they are removed, on the { char.
I have no idea about how R works, however the error could point to the fact that what you are trying to pass is a javascript object, not a JSON. Javascript objects look like but are not identical to JSONs (see discussion here Javascript object Vs JSON)
One thing that you can try is passing in the data function a JSON string by calling the JSON.stringify function on your objects. Something like this:
var R = require("r-script");
var out = R("script.R")
.data(JSON.stringify({"Name" : "Mario", "Age" : 32, "Occupation" : "Plumber"}), JSON.stringify( {"Name" : "Peach", "Age" : 21, "Occupation" : "Princess"}),JSON.stringify ({}), JSON.stringify({"Name" : "Bowser", "Occupation" : "Koopa"}))
.callSync();
console.log(out);
It's a longshot but it shows a general direction on which you can debug
I managed to found a simple solution, the Manos Agelidis answer did put me in the right direction.
Basically, I have able to parse the input string using:
string = paste(input, collapse=",")
string = paste("[",string,"]")
frame = fromJSON(string)
and in NodeJS:
var out = R("script.R")
.data('{"Name":"Mario","Age":32,"Occupation":"Plumber"}',
'{"Name":"Peach","Age":21,"Occupation":"Princess"}',
'{}',
'{"Name":"Bowser","Occupation":"Koopa"}')
.callSync();
fromJSON requires a vector but in string form, and not a literal vector. Therefore, what I needed to do what to create a string using the elements of the input and to add [ and ] to the begging and end of the string, respectively. This did convert to a data frame properly.

Documentation of squared bracket `[` function

I have a function in R that looks somewhat like this:
setMethod('[', signature(x="stack"),definition=function(x,i,j,drop){
new('class', as(x, "SpatialPointsDataFrame")[i,]) })
I use it to get a single element out of a stacked object. For the package I'm building I need a .Rd file to document the function. I stored it as [.Rd but somehow the R CMD check does not see this. It returns:
Undocumented S4 methods: generic '[' and siglist 'MoveStack,ANY,ANY'
The [.Rd file starts with these lines:
\name{[}
\alias{[}
\alias{[,stack,ANY,ANY-method}
\docType{methods}
\title{Returns an object from a stack}
\description{Returning a single object}
\usage{
\S4method{\[}{stack,ANY,ANY}(x,i,y,drop)
}
Any idea how I make R CMD check aware of this file?
If you look at the source code of the sp package, for example SpatialPolygons-class.Rd, the Methods section:
\section{Methods}{
Methods defined with class "SpatialPolygons" in the signature:
\describe{
\item{[}{\code{signature(obj = "SpatialPolygons")}: select subset of (sets of) polygons; NAs are not permitted in the row index}
\item{plot}{\code{signature(x = "SpatialPolygons", y = "missing")}:
plot polygons in SpatialPolygons object}
\item{summary}{\code{signature(object = "SpatialPolygons")}: summarize object}
\item{rbind}{\code{signature(object = "SpatialPolygons")}: rbind-like method}
}
}
method for [ is defined.
Name and class of the file are
\name{SpatialPolygons-class}
\alias{[,SpatialPolygons-method}
If you look at the help page for ?SpatialPolygons you should see
> Methods
>
> Methods defined with class "SpatialPolygons" in the signature:
>
> [ signature(obj = "SpatialPolygons"): select subset of (sets of)
> polygons; NAs are not permitted in the row index
>
So I would venture a guess that if you specify a proper (ASCII named) file name, give it an alias as in the above example, you should be fine.

Resources