Reputation: 121
I have a JSON file like this:
{
"result":
{
"id": "123456789012345",
"name": "Example data",
},
"parents":
{
"p1":
{
"parentGender": "M",
"parentName": "George",
"kids":
{
"1":
{
"name": "Alan",
"gender": "M",
"age": "10"
},
"2":
{
"name": "Adam",
"gender": "M",
"age": "15"
}
}
},
"p2":
{
"parentGender": "F",
"parentName": "Samantha",
"kids":
{
"1":
{
"name": "James",
"gender": "M",
"age": "9"
}
}
},
"p3":
{
"parentGender": "M",
"parentName": "John",
"kids":
{
"1":
{
"name": "Beatrice",
"gender": "F",
"age": "11"
},
"2":
{
"name": "Ben",
"gender": "M",
"age": "8"
},
"3":
{
"name": "Dorothy",
"gender": "F",
"age": "12"
}
}
}
}
}
I would like to retrieve all kids, and their names (and parents names) like this:
name,gender, age, parentGender, parentName,id
Alan,M,10, M,George,p1
Adam,M,15, M,George,p1
James,M,9, F,Samantha,p1
...
I know how to get particular/ single item like:
library(jsonlite)
es<-fromJSON("./json_example2.json" )
es$parents$p1$kids$`1`$name
But how to make a loop thru kids while we have different counts in collections? Finally I would like to create a code based on these data like: If (Gender is "M" and age >10) do bar chart of X If (Gender is "F" and age <10) do pie chart of Y...
When I will have it in table like below this should be easier, but not sure which approach is better.
Regards, Piotr
Upvotes: 2
Views: 322
Reputation: 988
If your JSON has different counts in collections, a "for in" loop is enough. The following code should do the trick:
library(jsonlite)
es<-fromJSON("./json_example2.json" )
parentId <- names(es$parents)
df <- data.frame()
for(i in 1:length(parentId)) {
p <- es$parents[[i]]
id <- parentId[i]
parentGender <- as.character(p$parentGender)
parentName <- as.character(p$parentName)
for(k in p$kids) {
name <- as.character(k$name)
gender <- as.character(k$gender)
age <- as.numeric(k$age)
df <- rbind(df, data.frame(name, gender, age, parentGender, parentName, id))
}
}
print(df)
To filter the age and gender:
barChartData <- df[which(df$age > 10 & df$gender == "M"), ]
For the sake of completeness, if your JSON has more complex depths (not the exemplified case), then you may use a recursive solution or stack (similar to iterate over a tree) .
Hope it helps! :)
Upvotes: 1
Reputation: 20463
If you want a purrr
functional approach, you could do:
library(tidyverse)
parents <- es$parents %>% enframe('parentID', 'parentInfo')
result_df <-
parents %>%
mutate(parent_gender = parentInfo %>% map_chr("parentGender"),
parent_name = parentInfo %>% map_chr("parentName"),
kid_info = parentInfo %>% map("kids") %>%
map(. %>% map_df(`[`, c("name", "gender", "age")))) %>%
select(-parentInfo) %>%
unnest()
# A tibble: 6 x 6
parentID parent_gender parent_name name gender age
<chr> <chr> <chr> <chr> <chr> <chr>
1 p1 M George Alan M 10
2 p1 M George Adam M 15
3 p2 F Samantha James M 9
4 p3 M John Beatrice F 11
5 p3 M John Ben M 8
6 p3 M John Dorothy F 12
Upvotes: 2