Reputation: 379
How to create a JSON object with data.frame(MyData) something like below.I tried other methods but this problem looks unique.
ID Station Size
1 Zeta Big
2 Zeta Medium
3 Zeta small
4 Yota Big
5 Yota Medium
6 Yota small
Expected result
{
"name": "bubble",
"children": [{
"name": "Zeta",
"children": [{
"name": "big"
}, {
"name": "Medium"
}, {
"name": "small"
}]
}, {
"name": "Yota",
"children": [{
"name": "big"
}, {
"name": "Medium"
}, {
"name": "small"
}]
}]
}
Here is what I searched and was not able to alter
makeList<-function(x){
if(ncol(x)>2){
listSplit<-split(x[-1],x[1],drop=T)
lapply(names(listSplit),function(y){list(name=y,children=makeList(listSplit[[y]]))})
}else{
lapply(seq(nrow(x[1])),function(y){list(name=x[,-1][y])})
}
}
jsonOut<-toJSON(list(name="MyData",children=makeList(MyData[1])))
cat(jsonOut)
Upvotes: 3
Views: 1961
Reputation: 8333
Data
The data I'm using is
df <- data.frame(Station = c(rep("Zeta", 3), rep("Yota", 3)),
Size = rep(c("Big","Medium","Small"),2), stringsAsFactors = F)
Method
Working backwards we can see the structure we're after
t <- "{\"name\": \"bubble\",\"children\": [{\"name\": \"Zeta\",\"children\": [{\"name\": \"big\"}, {\"name\": \"Medium\" }, {\"name\": \"small\"}]}, {\"name\": \"Yota\",\"children\": [{\"name\": \"big\"}, {\"name\": \"Medium\"}, {\"name\": \"small\"}]}]}\""
library(jsonlite)
l <- fromJSON(t)
str(l)
#List of 2
#$ name : chr "bubble"
#$ children:'data.frame': 2 obs. of 2 variables:
# ..$ name : chr [1:2] "Zeta" "Yota"
# ..$ children:List of 2
# .. ..$ :'data.frame': 3 obs. of 1 variable:
# .. .. ..$ name: chr [1:3] "big" "Medium" "small"
# .. ..$ :'data.frame': 3 obs. of 1 variable:
# .. .. ..$ name: chr [1:3] "big" "Medium" "small"
To reconstruct this we need
## first element
lst <- list(name = "bubble")
## second element
l_child1 <- l$children$children[[1]]
l_child2 <- l$children$children[[2]]
l_child <- list(data.frame(name=l_child1), data.frame(name=l_child2))
n <- c("Zeta", "Yota")
df_child <- data.frame(name = n, stringsAsFactors = F)
df_child$children <- l_child
lst <- list(name = "bubble", children = df_child)
toJSON(lst, pretty=F)
# {"name":["bubble"],"children":[{"name":"Zeta","children":[{"name":"big"},{"name":"Medium"},{"name":"small"}]},{"name":"Yota","children":[{"name":"big"},{"name":"Medium"},{"name":"small"}]}]}
So we know we need the structures of l_child1, l_child2, l_child, df_child
, but how do we get there from our original df
, and for the general case?
Solution
df$Size
gives us our l_child
lists, and there is a size for each Station
. So we can use lapply
to give us our lists of children, for each 'group' of Station.
n <- unique(df$Station)
l_child <- lapply(1:length(n), FUN=function(x){
t <- data.frame(name = (df[df$Station == n[x], "Size"]), stringsAsFactors=F)
return(t)
})
And we can now construct our final list
df_child <- data.frame(name = n, stringsAsFactors = FALSE)
df_child$children <- l_child
lst <- list(name = "bubble", children = df_child)
And to check:
> toJSON(lst, pretty=T)
{
"name": ["bubble"],
"children": [
{
"name": "Zeta",
"children": [
{
"name": "Big"
},
{
"name": "Medium"
},
{
"name": "Small"
}
]
},
... etc...
Upvotes: 2