आर

2011-11-27 8 views
18

से जेएसओएन आउटपुट स्वरूपित करने की रणनीतियां मैं आर से जेएसओएन फाइल बनाने का सबसे अच्छा तरीका जानने की कोशिश कर रहा हूं। मेरे पास निम्नलिखित डेटाफ्रेम tmpR में है।आर

> tmp 
    gender age welcoming proud tidy unique 
1  1 30   4  4 4  4 
2  2 34   4  2 4  4 
3  1 34   5  3 4  5 
4  2 33   2  3 2  4 
5  2 28   4  3 4  4 
6  2 26   3  2 4  3 

dput(tmp) के उत्पादन में इस प्रकार है:

tmp <- structure(list(gender = c(1L, 2L, 1L, 2L, 2L, 2L), age = c(30, 
34, 34, 33, 28, 26), welcoming = c(4L, 4L, 5L, 2L, 4L, 3L), proud = c(4L, 
2L, 3L, 3L, 3L, 2L), tidy = c(4L, 4L, 4L, 2L, 4L, 4L), unique = c(4L, 
4L, 5L, 4L, 4L, 3L)), .Names = c("gender", "age", "welcoming", 
"proud", "tidy", "unique"), na.action = structure(c(15L, 39L, 
60L, 77L, 88L, 128L, 132L, 172L, 272L, 304L, 305L, 317L, 328L, 
409L, 447L, 512L, 527L, 605L, 618L, 657L, 665L, 670L, 708L, 709L, 
729L, 746L, 795L, 803L, 826L, 855L, 898L, 911L, 957L, 967L, 983L, 
984L, 988L, 1006L, 1161L, 1162L, 1224L, 1245L, 1256L, 1257L, 
1307L, 1374L, 1379L, 1386L, 1387L, 1394L, 1401L, 1408L, 1434L, 
1446L, 1509L, 1556L, 1650L, 1717L, 1760L, 1782L, 1814L, 1847L, 
1863L, 1909L, 1930L, 1971L, 2004L, 2022L, 2055L, 2060L, 2065L, 
2082L, 2109L, 2121L, 2145L, 2158L, 2159L, 2226L, 2227L, 2281L 
), .Names = c("15", "39", "60", "77", "88", "128", "132", "172", 
"272", "304", "305", "317", "328", "409", "447", "512", "527", 
"605", "618", "657", "665", "670", "708", "709", "729", "746", 
"795", "803", "826", "855", "898", "911", "957", "967", "983", 
"984", "988", "1006", "1161", "1162", "1224", "1245", "1256", 
"1257", "1307", "1374", "1379", "1386", "1387", "1394", "1401", 
"1408", "1434", "1446", "1509", "1556", "1650", "1717", "1760", 
"1782", "1814", "1847", "1863", "1909", "1930", "1971", "2004", 
"2022", "2055", "2060", "2065", "2082", "2109", "2121", "2145", 
"2158", "2159", "2226", "2227", "2281"), class = "omit"), row.names = c(NA, 
6L), class = "data.frame") 

rjson पैकेज का उपयोग करना, मैं लाइन toJSON(tmp) जो निम्नलिखित JSON फ़ाइल का उत्पादन चलाएँ:

{"gender":[1,2,1,2,2,2], 
"age":[30,34,34,33,28,26], 
"welcoming":[4,4,5,2,4,3], 
"proud":[4,2,3,3,3,2], 
    "tidy":[4,4,4,2,4,4], 
    "unique":[4,4,5,4,4,3]} 

मैं भी साथ प्रयोग RJSONIO पैकेज; toJSON() का उत्पादन वही था।

{"traits":["gender","age","welcoming","proud", "tidy", "unique"], 
    "values":[ 
      {"gender":1,"age":30,"welcoming":4,"proud":4,"tidy":4, "unique":4}, 
      {"gender":2,"age":34,"welcoming":4,"proud":2,"tidy":4, "unique":4}, 
      .... 
      ] 

मैं कैसे सबसे अच्छा यह करने के लिए यकीन नहीं है: क्या मैं उत्पादन करने के लिए चाहते हैं निम्नलिखित संरचना है। मुझे एहसास है कि मैं इसे python का उपयोग करके लाइन से लाइन कर सकता हूं लेकिन मुझे लगता है कि ऐसा करने का शायद एक बेहतर तरीका है। मैं भी महसूस करते हैं कि R में मेरे डेटा संरचना मेटा जानकारी मेरी JSON फ़ाइल (विशेष रूप से traits लाइन) में वांछित को प्रतिबिंबित नहीं करता है, लेकिन मैं मुख्य रूप से डेटा मैं के रूप में लाइन

{"gender":1,"age":30,"welcoming":4,"proud":4,"tidy":4, "unique":4} 

प्रकार फ़ॉर्मेट उत्पादन में दिलचस्पी है मैन्युअल रूप से पहली पंक्ति जोड़ सकते हैं।


संपादित करें: जहाँ लेखक एक समान समस्या से निपटा है और एक समाधान प्रदान की मैं एक उपयोगी blog पद मिल गया। यह फ़ंक्शन डेटा फ्रेम से स्वरूपित JSON फ़ाइल उत्पन्न करता है।

toJSONarray <- function(dtf){ 
clnms <- colnames(dtf) 

name.value <- function(i){ 
quote <- ''; 
# if(class(dtf[, i])!='numeric'){ 
if(class(dtf[, i])!='numeric' && class(dtf[, i])!= 'integer'){ # I modified this line so integers are also not enclosed in quotes 
quote <- '"'; 
} 

paste('"', i, '" : ', quote, dtf[,i], quote, sep='') 
} 

objs <- apply(sapply(clnms, name.value), 1, function(x){paste(x, collapse=', ')}) 
objs <- paste('{', objs, '}') 

# res <- paste('[', paste(objs, collapse=', '), ']') 
res <- paste('[', paste(objs, collapse=',\n'), ']') # added newline for formatting output 

return(res) 
} 
+0

साल पर के बाद से यह सवाल पूछा गया था चले गए हैं। क्या मैं लाइब्रेरी (जेसनलाइट) को देखने का सुझाव दे सकता हूं - किसी और ने नीचे जवाब दिया है। इसे लागू() रूपांतरित करने की आवश्यकता नहीं है और सीधे अपेक्षित JSON आउटपुट उत्पन्न करता है। – ripvlan

+1

@ripvlan - उत्तर के रूप में jsonlite चिह्नित – djq

उत्तर

7

पैकेज jsonlite का उपयोग करना:

> jsonlite::toJSON(list(traits = names(tmp), values = tmp), pretty = TRUE) 
{ 
    "traits": ["gender", "age", "welcoming", "proud", "tidy", "unique"], 
    "values": [ 
    { 
     "gender": 1, 
     "age": 30, 
     "welcoming": 4, 
     "proud": 4, 
     "tidy": 4, 
     "unique": 4 
    }, 
    { 
     "gender": 2, 
     "age": 34, 
     "welcoming": 4, 
     "proud": 2, 
     "tidy": 4, 
     "unique": 4 
    }, 
    { 
     "gender": 1, 
     "age": 34, 
     "welcoming": 5, 
     "proud": 3, 
     "tidy": 4, 
     "unique": 5 
    }, 
    { 
     "gender": 2, 
     "age": 33, 
     "welcoming": 2, 
     "proud": 3, 
     "tidy": 2, 
     "unique": 4 
    }, 
    { 
     "gender": 2, 
     "age": 28, 
     "welcoming": 4, 
     "proud": 3, 
     "tidy": 4, 
     "unique": 4 
    }, 
    { 
     "gender": 2, 
     "age": 26, 
     "welcoming": 3, 
     "proud": 2, 
     "tidy": 4, 
     "unique": 3 
    } 
    ] 
} 
+1

हाय एलेक्स - मुझे यह जवाब सबसे अच्छा लगा। jsonlite उपरोक्त @civilstat उत्तर में वर्णित अनुसार()/लागू() के बिना डेटा.फ्रेम और आउटपुट को समझता है। इसके अलावा - मैं आरजेएसओएनआईओ के साथ एक मुद्दे में भाग गया कि मैं इसे हल करने में सक्षम नहीं हूं क्योंकि सभी मानों को 1 के सरणी होने का कारण बनता है। Jsonlite में यह समस्या नहीं थी। – ripvlan

+0

प्रतिक्रिया के लिए धन्यवाद, मुझे खुशी है कि आपको यह उपयोगी लगता है। – Alex

4

मुझे ऐसा लगता है कि आप उचित apply बयान के साथ JSON करने के लिए अपने data.frame की प्रत्येक पंक्ति भेजकर ऐसा कर सकते हैं।

एक ही पंक्ति के लिए:

library(RJSONIO) 

> x <- toJSON(tmp[1, ]) 
> cat(x) 
{ 
"gender": 1, 
"age":  30, 
"welcoming": 4, 
"proud": 4, 
"tidy": 4, 
"unique": 4 
} 

पूरे data.frame:

x <- apply(tmp, 1, toJSON) 
cat(x) 
{ 
"gender": 1, 
"age":  30, 
"welcoming": 4, 
"proud": 4, 
"tidy": 4, 
"unique": 4 
} { 

... 

} { 
"gender": 2, 
"age":  26, 
"welcoming": 3, 
"proud": 2, 
"tidy": 4, 
"unique": 3 
} 
+0

धन्यवाद @Andrie, यह एक अच्छा विचार है। मैं यह समझने की कोशिश कर रहा हूं कि प्रत्येक लाइन के अंत में इस तरह से कुछ का उपयोग करके ''' को कैसे सम्मिलित किया जाए:' x <- लागू करें (tmp, 1, function (tmp) {paste (toJSON, ',')}) '। क्या 'toJSON' से वापस लौटने के लिए कुछ जोड़ने का कोई तरीका है? – djq

+0

बस इसे समझ लिया: 'x <- लागू करें (tmp, 1, function (tmp) {पेस्ट (toJSON (tmp), ',')})। अभी भी 'लागू' की लटका मिल रही है! – djq

+0

@celenius: यह संदिग्ध रूप से लगता है जैसे आप JSON के बिट्स लिखने की कोशिश कर रहे हैं, जो केवल आँसू में खत्म हो जाएगा। डेटा को उस फ़ॉर्म में हेरफेर करने के लिए बेहतर है जहां 'toJSON' को कॉल करना आपको वह चाहिए जो आप चाहते हैं। मेरा जवाब देखें –

14

बिल्डिंग apply साथ Andrie के विचार पर, आप बिल्कुल आप क्या चाहते हैं toJSON कॉल करने से पहले tmp चर संशोधित करके प्राप्त कर सकते हैं।

library(RJSONIO) 
modified <- list(
    traits = colnames(tmp), 
    values = unname(apply(tmp, 1, function(x) as.data.frame(t(x)))) 
) 
cat(toJSON(modified)) 
+0

+1 हां, सहमत है कि यह बेहतर दृष्टिकोण है। – Andrie

+0

एक समस्या जो मैंने दोनों दृष्टिकोणों ('rjson' और 'RJSONIO') के साथ की है, यह है कि वे सभी संख्याओं को तारों में परिवर्तित करते हैं। उदाहरण के लिए '2'' 2 "' बन जाता है। मेरे प्रश्न के हिस्से के रूप में चिपकने वाला कोड स्निपेट इस समस्या से बचाता है क्योंकि यह 'संख्यात्मक' और 'पूर्णांक' के लिए जांच करता है। शायद मुझे इसे एक जवाब के रूप में जोड़ना चाहिए। – djq

+0

@celenius: आपके चर 'tmp' पर लागू मेरा समाधान पूर्णांक पूर्णांक है, परिवर्तित-से-स्ट्रिंग पूर्णांक नहीं। क्या आप वाकई मूर्खतापूर्ण कुछ नहीं कर रहे हैं? –

9

आगे Andrie और रिची के विचारों पर बिल्डिंग, alply बजाय apply का उपयोग करने के लिए पात्रों संख्या परिवर्तित करने से बचने के लिए:

library(RJSONIO) 
library(plyr) 
modified <- list(
    traits = colnames(tmp), 
    values = unname(alply(tmp, 1, identity)) 
) 
cat(toJSON(modified)) 

plyr के alplyapply के समान है लेकिन स्वचालित रूप से एक सूची लौटाती है; जबकि रिची कपास के जवाब के अंदर अधिक जटिल कार्य के बिना, apply एक वेक्टर या सरणी लौटाएगा। और t समेत उन अतिरिक्त चरणों का अर्थ है कि यदि आपके डेटासेट में कोई गैर-संख्यात्मक कॉलम हैं, तो संख्याएं स्ट्रिंग में परिवर्तित हो जाएंगी। तो alply का उपयोग उस चिंता से बचाता है।

उदाहरण के लिए, अपने tmp डाटासेट लेने के लिए और जोड़ने

tmp$grade <- c("A","B","C","D","E","F") 

फिर इस कोड की तुलना (alply के साथ) अन्य उदाहरण बनाम (apply के साथ)।

2

एक और विकल्प split का उपयोग data.frame को एन पंक्तियों के साथ एन डेटा.फ्रेम में 1 पंक्ति के साथ विभाजित करने के लिए करना है।

library(RJSONIO) 
modified <- list(
    traits = colnames(tmp), 
    values = split(tmp, seq_len(nrow(tmp))) 
) 
cat(toJSON(modified))