本節書摘來自華章出版社《r的極客理想—工具篇》一 書中的第1章,第1.6節,作者:張丹,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。
問題
如何讓r語言的資料類型轉換成json資料類型?

引言
json作為一種輕量級資料格式,被大量地應用在各種程式環境中。json(javascript object notation)是javascript的内嵌的标準對象,同時也是mongodb的表結構存儲類型。json是半結構化的,可以表達出豐富的文檔含義。json文檔比xml文檔要少很多,更适合于網絡傳輸。早期r語言程式設計很少會用到json,但随着r語言的壯大,r也在伸向各種領域,json就是與其他領域的一個交點。如何讓r語言傻瓜式轉型json呢?請看下文介紹。
rjson是一個r語言與json進行轉換的包,非常簡單,支援r自身語言轉型和基于c類庫的轉型兩種方式。rjson包提供的函數隻有3個,fromjson(), newjsonparser(), tojson()。 後面我們将介紹如何使用rjson包。本節使用的系統環境是:
windows 7: x86_64-w64-mingw32/x64 (64-bit)
r: version 3.0.1
注 rjson同時支援windows 7環境和linux環境。
安裝并加載rjson
接下來,我們進行測試。建立json檔案fin0.json:
調用函數fromjson(): 從json到r
從fin0.json檔案中,讀取json并解析成r語言對象。我們通常把位元組或者文字格式轉型為程式對象的過程叫反序列化過程,與之相反的過程,叫做序列化過程。
我們看到原json對象轉型後,除最内層外,其他都被解析為r的清單(list)類型,最内層則是基本(numeric,character)類型。在r對象結構中取json資料的一個葉子節點,json的索引路徑為 json.table1.data.code[0]。
tojson() 從r到json
把r對象轉型為json串,這個過程叫做序列化過程。還以剛才的json_data為例。
我們隻要使用tojson()函數,就可以實作r對象向json的轉型。如果用print()函數輸出,結果就是帶轉義的輸出(");如果直接用cat函數輸出,結果就是标準的json串格式。把json輸出到檔案fin0_out.json, 有2種方法,即writelines()和sink()。
雖然寫法不同,但是輸出結果是一個樣的,writelines最後建立一個空行。
c語言庫和r語言庫轉型,并進行性能測試
我們對fromjson進行性能測試:
system.time( y <- fromjson(json_str,method="c") )
使用者 系統 流逝
0 0 0
system.time( y2 <- fromjson(json_str,method = "r") )
使用者 系統 流逝
0.02 0.00 0.02
system.time( y3 <- fromjson(json_str) )
system.time( y <- tojson(json_data,method="c") )
0 0 0
system.time( y2 <- tojson(json_data,method = "r") )
使用者 系統 流逝
0.02 0.00 0.01
system.time( y3 <- tojson(json_data) )
安裝并加載rjsonio
install.packages("rjsonio") library(rjsonio)
fromjson() 從json到r
同rjson一樣,測試fromjson()函數。
json_data <- fromjson(paste(readlines("fin0.json"), collapse="")) json_data
$table1
$table1$time
[1] "130911"
$table1$data
$table1$data$code
[1] "tf1312" "tf1403" "tf1406"
$table1$data$rt_time
[1] 130911 130911 130911
$table2
$table2$time
$table2$data
$table2$data$contract
[1] "tf1312" "tf1312" "tf1403"
$table2$data$jtid
[1] 99 65 21
json_data$table1$data$code
json_data$table1$data$code[1]
[1] "tf1312"
json_str<-tojson(json_data) print(json_str)
[1] "{n "table1": {n "time": "130911",n"data": {n "code":
["tf1312", "tf1403", "tf1406" ],n"rt_time": [ 1.3091e+05, 1.3091e+05,
1.3091e+05 ] n} n},n"table2": {n "time": "130911",n"data": {n
"contract": [ "tf1312", "tf1312", "tf1403" ],n"jtid": [99,
65,21 ] n} n} n}"
cat(json_str)
{
"table1": {
"time": "130911",
"data": {
"code": [ "tf1312", "tf1403", "tf1406" ],
"rt_time": [ 1.3091e+05, 1.3091e+05, 1.3091e+05 ]
}
},
"table2": {
"contract": [ "tf1312", "tf1312", "tf1403" ],
"jtid": [99,65,21 ]
writelines(json_str, "fin0_io.json")
檔案結果:
"jtid": [ 99, 65, 21 ]
isvalidjson(json_str)
error in file(con, "r") : cannot open the connection
isvalidjson(json_str,true) #合法json
[1] true
isvalidjson(i('{"foo" : "bar"}')) #合法json
isvalidjson(i('{foo : "bar"}')) #不合法json
[1] false
asjsvars() 轉換為javascript變量格式
cat(asjsvars( a = 1:10, mymatrix = matrix(1:15, 3, 5))) a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] ;
mymatrix = [ [ 1, 4, 7, 10, 13 ],
[
]
df<-data.frame( code=c('tf1312','tf1310','tf1313'),
rt_time=c("152929","152929","152929"),
rt_latest=c(93.76,93.76,93.76),
rt_bid1=c(93.76,93.76,93.76),
rt_ask1=c(90.76,90.76,90.76),
rt_bsize1=c(2,3,1),
rt_asize1=c(100,1,11),
optionvalue=c(-0.4,0.2,-0.1),
diffvalue=c(0.6,0.6,0.5)
)
df
1 tf1312 152929 93.76 93.76 90.76 2 100 -0.4 0.6
2 tf1310 152929 93.76 93.76 90.76 3 1 0.2 0.6
3 tf1313 152929 93.76 93.76 90.76 1 11 -0.1 0.5
cat(tojson(df))
"code": ["tf1312", "tf1310", "tf1313"],
"rt_time": ["152929", "152929", "152929"],
"rt_latest": [93.76, 93.76, 93.76],
"rt_bid1": [93.76, 93.76, 93.76],
"rt_ask1": [90.76, 90.76, 90.76],
"rt_bsize1": [2, 3, 1],
"rt_asize1": [100, 1, 11],
"optionvalue": [-0.4, 0.2, -0.1],
"diffvalue": [0.6, 0.6, 0.5]
library(plyr) #用plyr進行資料轉換 cat(tojson(unname(alply(df, 1, identity))))
"code": "tf1312",
"rt_time": "152929",
"rt_latest": 93.76,
"rt_bid1": 93.76,
"rt_ask1": 90.76,
"rt_bsize1": 2,
"rt_asize1": 100,
"optionvalue": -0.4,
"diffvalue": 0.6
"code": "tf1310",
"rt_time": "152929",
"rt_latest": 93.76,
"rt_bid1": 93.76,
"rt_ask1": 90.76,
"rt_bsize1": 3,
"rt_asize1": 1,
"optionvalue": 0.2,
"diffvalue": 0.6
"code": "tf1313",
"rt_bsize1": 1,
"rt_asize1": 11,
"optionvalue":-0.1,
"diffvalue": 0.5
library(rjson)
a=rep(letters,10000),
b=rnorm(260000),
c=as.factor(sys.date()-rep(1:260000))
system.time(rjson::tojson(df)) 1.01 0.02 1.03
1.01 0.03 1.04
0.98 0.05 1.03
system.time(rjsonio::tojson(df)) 2.23 0.02 2.24
2.30 0.00 2.29
2.25 0.01 2.26
library(plyr)
a=rep(letters,100),
b=rnorm(2600),
c=as.factor(sys.date()-rep(1:2600))
0.01 0.00 0.02
system.time(rjson::tojson(unname(alply(df, 1, identity))))
1.55 0.02 1.56
0.83 0.00 0.83
0.03 0.00 0.03
0.04 0.00 0.03
system.time(rjsonio::tojson(unname(alply(df, 1, identity))))
2.82 0.02 2.84
2.06 0.00 2.06