Как написать json с детьми из R

Я хочу превратить R data.frame в объект JSON, чтобы использовать его для подготовки визуализации данных с помощью d3.js. Я нашел много вопросов, которые спрашивали, как получить JSON в R, но очень мало о том, как записывать данные из R в JSON.

Особая проблема заключается в том, что файл JSON должен быть вложен с использованием факторов, то есть столбцов data.frame. Я думаю, что запись из вложенных списков может быть решением, но я уже не смог создать вложенный список из data.frame 🙁

У меня есть предварительный пример:

это представляет собой мой data.frame (называемый «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 

теперь я хочу превратить его в нечто вроде этого корректного json-формата, включая дочерние узлы:

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

Если бы кто-нибудь мог мне помочь, я был бы очень благодарен! Спасибо

Это рекурсивный подход, который является более чистым:

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

Использование комбинации split и subset может получить то, что вы хотите. Например

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

Я откладываю ответ от ответа user1609452 и отвечаю на вопрос о нестандартных иерархиях файлов. Если у вас есть столбец, в котором некоторые данные имеют дочерние элементы, а некоторые – нет, используйте следующее:

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

В основном мы проверяем, имеет ли текущая строка больше детей или просто нужно добавить к ней размер.

  • Как форматировать вывод печати или строку в фиксированную ширину?
  • Как вы форматируете дату и время в Android?
  • Как получить выбранный пользователем формат даты в Android?
  • Как отформатировать DateTime до 24 часов?
  • Как изменить несколько форматов даты в одном столбце
  • Как анализировать дату в Date?
  • Как преобразовать String в Date без знания формата?
  • Формат метода (String, Object ) в типе String не применим для аргументов (...)
  • Где спецификатор формата DateTime 'Z'?
  • Как преобразовать миллисекунды в читаемую человеком форму?
  • Как отформатировать дату в angularjs
  • Давайте будем гением компьютера.