Cómo escribir a json con niños de R

Quiero convertir un R data.frame en un objeto JSON para usarlo para preparar visualizaciones de datos con d3.js. Encontré muchas preguntas que preguntaban cómo hacer que JSON entrara en R, pero muy pocas sobre cómo escribir datos de R a JSON.

Un problema particular es que el archivo JSON debe estar nested utilizando factores, es decir, columnas de data.frame. Creo que escribir desde listas anidadas podría ser una solución, pero ya no pude crear una lista anidada desde un data.frame 🙁

Preparé un ejemplo:

esto representa mi data.frame (llamado “MyData”).

ID Location Station Size Percentage 1 Alpha Zeta Big 0.63 2 Alpha Zeta Medium 0.43 3 Alpha Zeta small 0.47 4 Alpha Yota Big 0.85 5 Alpha Yota Medium 0.19 6 Alpha Yota small 0.89 7 Beta Theta Big 0.09 8 Beta Theta Medium 0.33 9 Beta Theta small 0.79 10 Beta Meta Big 0.89 11 Beta Meta Medium 0.71 12 Beta Meta small 0.59 

ahora, quiero convertirlo en algo así como este formato json válido, incluidos los nodos hijos:

  { "name":"MyData", "children":[ { "name":"Alpha", "children":[ { "name":"Zeta", "children":[ { "name":"Big", "Percentage":0.63 }, { "name":"Medium", "Percentage":0.43 }, { "name":"Small", "Percentage":0.47 } ] }, { "name":"Yota", "children":[ { "name":"Big", "Percentage":0.85 }, { "name":"Medium", "Percentage":0.19 }, { "name":"Small", "Percentage":0.89 } ] } ] }, { "name":"Zeta", "children":[ { "name":"Big", "Percentage":0.63 }, { "name":"Medium", "Percentage":0.43 }, { "name":"Small", "Percentage":0.47 } ] }, { "name":"Yota", "children":[ { "name":"Big", "Percentage":0.85 }, { "name":"Medium", "Percentage":0.19 }, { "name":"Small", "Percentage":0.89 } ] } ] } 

¡Si alguien pudiera ayudarme, estaría muy agradecido! gracias

Este es un enfoque recursivo que es más limpio:

 require(RJSONIO) 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],Percentage=x[,2][y])}) } } jsonOut<-toJSON(list(name="MyData",children=makeList(MyData[-1]))) cat(jsonOut) 

El uso de una combinación de split y subset puede obtener lo que desea. Por ejemplo

 library(RJSONIO) list1<-split(subset(MyData,select=c(-Location)),Mydata$Location) list2<-lapply(list1,function(x){split(subset(x,select=c(-Station)),x$Station,drop=TRUE)}) list3<-lapply(list2,function(x){lapply(x,function(y){split(subset(y,select=c(-Size,-ID)),y$Size,drop=TRUE)})}) jsonOut<-toJSON(list(MyData=list3)) jsonOut1<-gsub('([^\n]*?): \\{\n "Percentage"','\\{"name":\\1,"Percentage"',jsonOut) jsonOut2<-gsub('"([^"]*?)": \\{','"name":"\\1","children":\\{',jsonOut1) cat(jsonOut2) { "name":"MyData","children":{ "name":"Alpha","children":{ "name":"Yota","children":{ {"name": "Big","Percentage": 0.85 }, {"name":"Medium","Percentage": 0.19 }, {"name":"small","Percentage": 0.89 } }, "name":"Zeta","children":{ {"name": "Big","Percentage": 0.63 }, {"name":"Medium","Percentage": 0.43 }, {"name":"small","Percentage": 0.47 } } }, "name":"Beta","children":{ "name":"Meta","children":{ {"name": "Big","Percentage": 0.89 }, {"name":"Medium","Percentage": 0.71 }, {"name":"small","Percentage": 0.59 } }, "name":"Theta","children":{ {"name": "Big","Percentage": 0.09 }, {"name":"Medium","Percentage": 0.33 }, {"name":"small","Percentage": 0.79 } } } } } 

Estoy evitando la respuesta de user1609452 y respondiendo a la pregunta sobre las jerarquías de archivos no regulares. Si tiene una columna donde algunos datos tienen hijos y otros no, use lo siguiente:

 makeList<-function(x){ if(ncol(x)>2){ listSplit<-split(x[-1],x[1],drop=T) lapply(names(listSplit),function(y){ if(as.character(listSplit[[y]][1,1]) > 0){ list(name=y,children=makeList(listSplit[[y]])) } else { list(name=y,size=listSplit[[y]][1,2]) } }) }else{ lapply(seq(nrow(x[1])),function(y){list(name=x[,1][y],size=x[,2][y])}) } } 

Básicamente, verificamos si la fila actual tiene más hijos o si simplemente debe tener un tamaño agregado.