本节书摘来自华章出版社《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