2016-01-31 39 views
2

如何用data.frame(MyData)創建類似於下面的JSON對象。我嘗試了其他方法,但這個問題看起來很獨特。在R中創建帶有多個子項的Json對象

ID Station Size 
1  Zeta Big 
2  Zeta Medium 
3  Zeta small 
4  Yota Big 
5  Yota Medium 
6  Yota small 

預期結果

{ 
    "name": "bubble", 
    "children": [{ 
     "name": "Zeta", 
     "children": [{ 
      "name": "big" 
     }, { 
      "name": "Medium" 
     }, { 
      "name": "small" 
     }] 
    }, { 
     "name": "Yota", 
     "children": [{ 
      "name": "big" 
     }, { 
      "name": "Medium" 
     }, { 
      "name": "small" 
     }] 
    }] 
} 

這裏是我的搜索,並沒有能夠改變

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) 
+1

我剛鍵入它在我的own..so現在..fixed它 – TheLion

+0

你受JSON結構的約束或者你是否靈活? – tospig

+0

我想要的JSON結構,因爲它的核心是寫入掃描該格式 – TheLion

回答

1

數據

我使用的數據是

df <- data.frame(Station = c(rep("Zeta", 3), rep("Yota", 3)), 
       Size = rep(c("Big","Medium","Small"),2), stringsAsFactors = F) 

方法

工作倒退,我們可以看到我們的結構之後

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" 

要重建這一點,我們需要

## 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"}]}]} 

所以我們知道我們需要的結構l_child1, l_child2, l_child, df_child,但我們如何從我們原來的df以及一般情況下到那裏?

解決方案

df$Size賦予我們l_child名單,並有一個大小爲每個Station。因此,我們可以使用lapply爲我們提供我們的兒童名單,每個車站的「組」。

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) 
}) 

而我們現在可以構建我們的最終名單

df_child <- data.frame(name = n, stringsAsFactors = FALSE) 
df_child$children <- l_child 

lst <- list(name = "bubble", children = df_child) 

,並檢查:

> toJSON(lst, pretty=T) 
{ 
    "name": ["bubble"], 
    "children": [ 
    { 
     "name": "Zeta", 
     "children": [ 
     { 
      "name": "Big" 
     }, 
     { 
      "name": "Medium" 
     }, 
     { 
     "name": "Small" 
     } 
     ] 
    }, 
    ... etc... 
+1

這真棒..一個小疑問,我如何得到n?在df_child < - data.frame(name = n,stringsAsFactors = FALSE)中推廣解決方案 – TheLion

+0

'n < - unique(df $ Station)'應該這樣做嗎?我已將它添加到我的答案中。 – tospig

+0

@TheLion實際上,'n'也是我們的'station_groups',所以我們不需要兩個變量 – tospig