आर

2012-10-10 9 views
17

से बच्चों के साथ जेसन को कैसे लिखना है I d3.js. के साथ डेटा विज़ुअलाइज़ेशन तैयार करने के लिए इसका उपयोग करने के लिए एक JSON ऑब्जेक्ट में एक आर डेटा.फ्रेम चालू करना चाहते हैं। मुझे बहुत सारे प्रश्न मिले जो पूछे गए कि जेएसओएन को आर में कैसे प्राप्त किया जाए, लेकिन आर से JSON तक डेटा कैसे लिखना है।आर

एक विशेष समस्या यह है कि JSON फ़ाइल को कारकों का उपयोग करके घोंसला होना चाहिए, यानी डेटा.फ्रेम के कॉलम। मुझे लगता है कि नीडिंत सूचियों से लिखित एक समाधान हो सकता है, लेकिन मैं पहले से ही एक data.frame :(

मैं एक उदाहरण preprared है से एक नेस्टेड सूची बनाने में विफल:

यह मेरा 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 
     } 
    ] 
    } 
    ] 
} 

अगर कोई मुझे बाहर मदद कर सकता है मैं बहुत आभारी होंगे! धन्यवाद

+1

आईएमओ, इसका JSON प्रति से कोई लेना देना नहीं है, बस आर के भीतर इस संरचना के समान है, और आप जाने के लिए अच्छे हैं। – aL3xa

+0

आप सही हैं, यह JSON निर्दिष्ट नहीं है। मेरा सवाल मुख्य रूप से इस विशिष्ट संरचना को प्राप्त करने के बारे में था। – Jens

उत्तर

23

के लिए यह एक पुनरावर्ती दृष्टिकोण है जो क्लीनर:

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

कमाल! अब यह सही दिखता है। 100% वैध जेसन। उत्पादन के साथ d3j काम करने के लिए मुझे "प्रतिशत" को "आकार" में बदलना पड़ा। लेकिन आपका दृष्टिकोण बिल्कुल शानदार है! मुझे आशा है कि मैं इसे समायोजित/विस्तारित कर सकता हूं। अरब धन्यवाद! – Jens

+1

यह एक साधारण फ़िल्टर जोड़कर गैर नियमित फाइल पदानुक्रमों (यानी पदानुक्रमों की संख्या स्थिर नहीं है) के लिए अनुकूलित किया जा सकता है:

x2 <- dplyr::filter(x, x[1] != "") ; listSplit <- split(x2[-1], x2[1], drop = TRUE)
PAC

+0

@PAC ठीक उसी स्थान पर जहां 'x2 <- फ़िल्टर (x, x [1] में ड्रॉप होता है! = ""); listSplit <- विभाजन (x2 [-1], x2 [1], ड्रॉप = TRUE) 'if (ncol (x)> 2) के ठीक बाद {' और बाकी सब कुछ छोड़ दें? –

2

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

हाँ दिलचस्प! लेकिन यहां चर "' आकार "और' "प्रतिशत" को अलग किया गया है। चर के प्रत्येक राज्य, यानी बिग, को एक प्रतिशत में अपने प्रतिशत मूल्य से जोड़ा जाना चाहिए। इसके अलावा '' बच्चे '' उपकरण गायब है। मैं विभाजन सूची के अपने विचार के साथ चारों ओर झुकाव करने की कोशिश करेंगे। thx – Jens

+0

मैंने 'आकार' और कुछ बदसूरत regex पर एक विभाजन जोड़ा। यह वही नहीं है जो आप चाहते हैं लेकिन यह शायद बंद हो सकता है। – user1609452

+0

aaah अब मैं समझता हूं कि यह कैसे काम करता है। धन्यवाद। हालांकि यह अभी भी पूरी तरह से काम नहीं कर रहा है, मैं आपको वोट दूंगा :) जेसन सत्यापनकर्ता अब शिकायत कर रहा है। मुझे लगता है कि [] ब्रैकेट गायब हैं। मैं आपके regex उदाहरणों को समायोजित करके इसे ठीक करने का प्रयास करूंगा। – Jens

0

मैं user1609452 के जवाब के बंद का समर्थन कर और गैर नियमित रूप से फ़ाइल पदानुक्रम के बारे में सवाल का जवाब देने pigging कर रहा हूँ। यदि आप एक कॉलम जहां कुछ डेटा बच्चे हैं और कुछ नहीं करते हैं, निम्नलिखित का उपयोग करते हैं:

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

असल में हम जाँच करता है, तो वर्तमान पंक्ति अधिक बच्चे हैं या यह सिर्फ आकार इसके परिशिष्ट में होगा करने की जरूरत है।