I'm creating a lexer which creates tokens and outputs them as a JSON list. The tokens are namedtuples.
More specifically, Token = namedtuple('Token', ['kind', 'lexeme'])
I create my tokens and print them using json.dumps(tokens, separators=(',', ':'))).
The output looks like this:
[
[
"INT",
"123"
],
[
"ID"
"b32"
],
]
I am looking to add a 'kind' and 'lexeme' label so that it looks like:
[
[
"kind" : "INT",
"lexeme" : "123"
],
[
"kind" : "ID"
"lexeme" : "b32"
],
]
Any ideas on how to do this?
Convert the namedtuple to dict before running json.dumps().
json.dumps([t._asdict() for t in tokens], separators=(',', ':'))
This should generate:
[
{
"kind" : "INT",
"lexeme" : "123"
},
{
"kind" : "ID",
"lexeme" : "b32"
}
]
Try it online!
Having two dataframes like
final_data2:
id type lang div
1 hola page es 1
and paths:
source target count
1 hola adios 1
I am able to combine both dataframes in the same JSON using jsonlite and the following code:
cat(toJSON(c(apply(final_data2,1,function(x)list(id = unname(x[1]),
type = unname(x[2]), lang = unname(x[3]), div = unname(x[4]))),
apply(paths,1,function(x)list(source = unname(x[1]), target = unname(x[2]),
playcount = unname(x[3])))), pretty = TRUE))
The result is a set of arrays as following:
[
{
"id": ["hola"],
"type": ["page"],
"lang": ["es"],
"div": ["1"]
},
{
"source": ["hola"],
"target": ["adios"],
"playcount": ["1"]
}
]
However, I need that the generated object contains two names (nodes and links), each nesting one of the previously defined dataframes. Therefore, the structure should look like this:
{
"nodes": [
{
"id": ["hola"],
"type": ["page"],
"lang": ["es"],
"div": ["1"]
}
],
"links": [
{
"source": ["hola"],
"target": ["adios"],
"playcount": ["1"]
}
]
}
Any tip on how to achieve it?
Just pass the data.frames as a named list into toJSON:
library(jsonlite)
df1 <- read.table(textConnection(" id type lang div
1 hola page es 1"), header = T)
df2 <- read.table(textConnection(" source target count
1 hola adios 1"), header = T)
toJSON(list(nodes = df1, links = df2), pretty = T)
# {
# "nodes": [
# {
# "id": "hola",
# "type": "page",
# "lang": "es",
# "div": 1
# }
# ],
# "links": [
# {
# "source": "hola",
# "target": "adios",
# "count": 1
# }
# ]
# }
JSON newbie here. Could you please help with parsing JSON files using R. I did try jsonlite & rjson, but keep getting errors.
Below is the data retrieved via the api.
data <- GET("http://svcs.ebay.com/services/search/FindingService/v1?OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.0.0&SECURITY-APPNAME=GLOBAL-ID=EBAY-US&RESPONSE-DATA-FORMAT=JSON&callback=_cb_findItemsByKeywords&REST-PAYLOAD&keywords=harry%20potter&paginationInput.entriesPerPage=10")
The JSON looks like this:
/**/_cb_findItemsByKeywords({
"findItemsByKeywordsResponse":[
{
"ack":[
"Success"
],
"version":[
"1.13.0"
],
"timestamp":[
"2016-01-29T16:36:25.984Z"
],
"searchResult":[
{
"#count":"1",
"item":[
{
"itemId":[
"371533364795"
],
"title":[
"Harry Potter: Complete 8-Film Collection (DVD, 2011, 8-Disc Set)"
],
"globalId":[
"EBAY-US"
],
"primaryCategory":[
{
"categoryId":[
"617"
],
"categoryName":[
"DVDs & Blu-ray Discs"
]
}
],
"galleryURL":[
"http:\/\/thumbs4.ebaystatic.com\/m\/mn5Agt0HFD89L7_-lqfrZZw\/140.jpg"
],
"viewItemURL":[
"http:\/\/www.ebay.com\/itm\/Harry-Potter-Complete-8-Film-Collection-DVD-2011-8-Disc-Set-\/371533364795"
],
"productId":[
{
"#type":"ReferenceID",
"__value__":"110258144"
}
],
"paymentMethod":[
"PayPal"
],
"autoPay":[
"false"
],
"postalCode":[
"60131"
],
"location":[
"Franklin Park,IL,USA"
],
"country":[
"US"
],
"shippingInfo":[
{
"shippingServiceCost":[
{
"#currencyId":"USD",
"__value__":"0.0"
}
],
"shippingType":[
"FlatDomesticCalculatedInternational"
],
"shipToLocations":[
"US",
"CA",
"GB",
"AU",
"AT",
"BE",
"FR",
"DE",
"IT",
"JP",
"ES",
"TW",
"NL",
"CN",
"HK",
"MX",
"DK",
"RO",
"SK",
"BG",
"CZ",
"FI",
"HU",
"LV",
"LT",
"MT",
"EE",
"GR",
"PT",
"CY",
"SI",
"SE",
"KR",
"ID",
"ZA",
"TH",
"IE",
"PL",
"RU",
"IL"
],
"expeditedShipping":[
"false"
],
"oneDayShippingAvailable":[
"false"
],
"handlingTime":[
"1"
]
}
],
"sellingStatus":[
{
"currentPrice":[
{
"#currencyId":"USD",
"__value__":"26.95"
}
],
"convertedCurrentPrice":[
{
"#currencyId":"USD",
"__value__":"26.95"
}
],
"sellingState":[
"Active"
],
"timeLeft":[
"P16DT3H12M6S"
]
}
],
"listingInfo":[
{
"bestOfferEnabled":[
"false"
],
"buyItNowAvailable":[
"false"
],
"startTime":[
"2016-01-15T19:43:31.000Z"
],
"endTime":[
"2016-02-14T19:48:31.000Z"
],
"listingType":[
"StoreInventory"
],
"gift":[
"false"
]
}
],
"returnsAccepted":[
"true"
],
"condition":[
{
"conditionId":[
"1000"
],
"conditionDisplayName":[
"Brand New"
]
}
],
"isMultiVariationListing":[
"false"
],
"topRatedListing":[
"true"
]
}
]
}
],
"paginationOutput":[
{
"pageNumber":[
"1"
],
"entriesPerPage":[
"1"
],
"totalPages":[
"138112"
],
"totalEntries":[
"138112"
]
}
],
"itemSearchURL":[
"http:\/\/www.ebay.com\/sch\/i.html?_nkw=harry+potter&_ddo=1&_ipg=1&_pgn=1"
]
}
]
})
The problem is that your data is not json, but it is JavaScript, jsonp to be exactly. If you just want to parse the JSON data you have to strip off the padding callback function.
req <- httr::GET("http://svcs.ebay.com/services/search/FindingService/v1?OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.0.0&SECURITY-APPNAME=YOUR-APP-123456&GLOBAL-ID=EBAY-US&RESPONSE-DATA-FORMAT=JSON&callback=_cb_findItemsByKeywords&REST-PAYLOAD&keywords=harry%20potter&paginationInput.entriesPerPage=10")
txt <- content(req, "text")
json <- sub("/**/_cb_findItemsByKeywords(", "", txt, fixed = TRUE)
json <- sub(")$", "", json)
mydata <- jsonlite::fromJSON(json)
Extra credit: alternatively you could use an actual JavaScript engine to parse the JavaScript:
library(V8)
ctx <- V8::v8()
ctx$eval("var out;")
ctx$eval("function _cb_findItemsByKeywords(x){out = x;}")
ctx$source("http://svcs.ebay.com/services/search/FindingService/v1?OPERATION-NAME=findItemsByKeywords&SERVICE-VERSION=1.0.0&SECURITY-APPNAME=YOUR-APP-123456&GLOBAL-ID=EBAY-US&RESPONSE-DATA-FORMAT=JSON&callback=_cb_findItemsByKeywords&REST-PAYLOAD&keywords=harry%20potter&paginationInput.entriesPerPage=10")
mydata <- ctx$get("out")
First, your json file seems to have a little issue. It should have started in the opening bracket "[".
I removed the text before it and I've tried this code, which worked perfectly:
library(rjson)
obj <- fromJSON(file = "v2.json")
That returned a list in obj with the contents of v2.json.
EDITED: Including a full functional soltion:
library(rjson)
library(stringr)
obj <- read.table("v2.json", sep = "\n", stringsAsFactors = FALSE, quote = "")
# Gets the first line with the string "[" ("\\" for scape)
firstline <- grep("\\[", obj[,1])[1]
# Gets the position of the string "[" in the line
fpos <- which(strsplit(obj[firstline, 1], "")[[1]] == "[")
# Gets the last line with the string "]"
lastline <- grep("\\]", obj[,1])
lastline <- lastline[length(lastline)]
# Gets the position of the string "]" in the line
lpos <- which(strsplit(obj[lastline, 1], "")[[1]] == "]")
# Changes the lines with the first "[" and the last "]" to keep the text
# between both (after "[" and before "]") if there is any.
obj[firstline, 1] <- str_sub(obj[firstline, 1], fpos)
obj[lastline, 1] <- str_sub(obj[lastline, 1], 1, lpos)
obj2 <- data.frame(obj[firstline:lastline, 1])
write.table(obj2, "v3.json", row.names = FALSE, col.names = FALSE, quote = FALSE)
obj3 <- fromJSON(file = "v3.json")
I have the following example.json. How can I parse it to csv in order to get the mean value (between ** mean_value **).
I want something like in example.csv:
305152,277504,320512
[
{
"name": "stats",
"columns": [
"time",
"mean"
],
"points": [
[
1444038496000,
**305152**
],
[
1444038494000,
**277504**
],
[
1444038492000,
**320512**
]
]
}
]
In python it looks like this
import json
results = []
with open('example.json', 'r') as f:
content = json.loads(f.read())
for element in content:
results.append(','.join([str(y[1]) for y in element['points']]))
with open('example.csv', 'w') as f:
f.write('\n'.join(results))