R和JSON的傻瓜式编程
R和JSON的傻瓜式编程
R的极客抱负系列文章,涵盖了R的思想,利用,东西,创新等的一系列要点,以我小我私家的进修和体验去诠释R的强大。
R语言作为统计学一门语言,一直在小众规模闪耀着光线。直到大数据的发作,R语言酿成了一门炙手可热的数据阐明的利器。跟着越来越多的工程配景的人的插手,R语言的社区在迅速扩大生长。此刻已不只仅是统计规模,教诲,银行,电商,互联网….都在利用R语言。
要成为有抱负的极客,我们不能逗留在语法上,要把握安稳的数学,概率,统计常识,同时还要有创新精力,把R语言发挥到各个规模。让我们一起动起来吧,开始R的极客抱负。
关于作者:
转载请注明出处:
http://blog.fens.me/r-json-rjson/
媒介
JSON作为一种轻量级数据名目,被大量地应用在各类措施情况中。JSON(JavaScript Object
Notation)是Javascript的内嵌的尺度工具,同时也是MongoDB的表布局存储范例。JSON是半布局化的,可以表达出富厚的文档含
义。JSON文档比XML文档要少许多,更适合于网络传输。
早期R语言编程很少会用到JSON,但跟着R语言的壮大,R也在伸向各类规模,JSON就是与其他规模的一个交点。
如何让R语言傻瓜式花转JSON?请看正文先容。
目次
- rjson包先容
- RJSONIO包先容
- 自界说JSON的实现
- toJSON机能较量: 我的测试功效rjson比RJSONIO更高效
1. rjson包先容
rjson是一个R语言与json举办转的包,是一个很是简朴的包,支持用 C类库转型和R语言自己转型两种方法。
rjson库,提供的函数只有3个,fromJSON(), newJSONParser(), toJSON()。 下面我们将先容rjson库如何利用。
我的系统情况
1). 安装和加载rjson
install.packages("rjson")
library(rjson)
新建一个JSON文件: fin0.json
~ vi fin0.json
{
"table1": {
"time": "130911",
"data": {
"code": [
"TF1312",
"TF1403",
"TF1406"
],
"rt_time": [
130911,
130911,
130911
]
}
},
"table2": {
"time": "130911",
"data": {
"contract": [
"TF1312",
"TF1312",
"TF1403"
],
"jtid": [
99,
65,
21
]
}
}
}
2). fromJSON() 从JSON到R
从fin0.json文件中,读取JSON并理会为R语言工具。
> 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
[1] "130911"
$table2$data
$table2$data$contract
[1] "TF1312" "TF1312" "TF1403"
$table2$data$jtid
[1] 99 65 21
我们看到原JSON,除最内层都被理会为R的list范例,最内层则是向量范例。
在R工具布局中取叶子节点, json.table1.data.code[0]
> json_data$table1$data$code
[1] "TF1312" "TF1403" "TF1406"
> json_data$table1$data$code[1]
[1] "TF1312"
3). toJSON() 从R到JSON
把R工具序列化为JSON串,还以适才的json_data为例
> json_str<-toJSON(json_data)
> print(json_str)
[1] "{\"table1\":{\"time\":\"130911\",\"data\":{\"code\":[\"TF1312\",\"TF1403\",\"TF1406\"],\"rt_time\":[130911,130911,130911]}},\"table2\":{\"time\":\"130911\",\"data\":{\"contract\":[\"TF1312\",\"TF1312\",\"TF1403\"],\"jtid\":[99,65,21]}}}"
> cat(json_str)
{"table1":{"time":"130911","data":{"code":["TF1312","TF1403","TF1406"],"rt_time":[130911,130911,130911]}},"table2":{"time":"130911","data":{"contract":["TF1312","TF1312","TF1403"],"jtid":[99,65,21]}}}
我们只要利用toJSON()函数,就可以实现R工具向JSON的转成。
假如用print功效就是带转义的输出(\”),直接用cat打印就是尺度的JSON串名目。
把JSON输出到文件:fin0_out.json, 有2种要领:
# writeLines
> writeLines(json_str, "fin0_out1.json")
# sink
> sink("fin0_out2.json")
> cat(json_str)
> sink()
#p#分页标题#e#
固然写法差异,输出功效是一个样的,writeLines最后新建一个空行。
{"table1":{"time":"130911","data":{"code":["TF1312","TF1403","TF1406"],"rt_time":[130911,130911,130911]}},"table2":{"time":"130911","data":{"contract":["TF1312","TF1312","TF1403"],"jtid":[99,65,21]}}}
4). 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) )
用户 系统 流逝
0 0 0
我们可以看到,C库比R库会快,因为数据量很小,所以0.02并不明明。当JSON串很大的时候,这个差距就会变得相当的大了。
别的,fromJSON默认利用的C库的要领,所以我们平时处理惩罚不消加method=’C’的参数。
toJSON的机能测试
> 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) )
用户 系统 流逝
0 0 0
同上的表明。
2. RJSONIO包先容
RJSONIO包,提供了2个主要的操纵,把JSON串反序列化成R工具,把R工具序列化成JSON串,两个主要的函数fromJSON(),
toJSON(),还包罗几个帮助函数asJSVars(), basicJSONHandler(), Bob(), isValidJSON(),
readJSONStream()。
RJSONIO包开拓,是办理了rjson包序列化大工具慢的问题。RJSONIO依赖于底层的C语言类库libjson。
1). 安装和加载RJSONIO
install.packages("RJSONIO")
library(RJSONIO)
2). 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
[1] "130911"
$table2$data
$table2$data$contract
[1] "TF1312" "TF1312" "TF1403"
$table2$data$jtid
[1] 99 65 21
我们发明与 rjson的理会功效是一样,都是基于list的
取叶子节点:
> json_data$table1$data$code
[1] "TF1312" "TF1403" "TF1406"
> json_data$table1$data$code[1]
[1] "TF1312"
3). toJSON() 从R到JSON
toJSON测试
> 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": {
"time": "130911",
"data": {
"contract": [ "TF1312", "TF1312", "TF1403" ],
"jtid": [ 99, 65, 21 ]
}
}
}
toJSON函数输出与rjson是纷歧样的,这个输出是名目化的。
输出到文件:
> writeLines(json_str, "fin0_io.json")
文件功效:
{
"table1": {
"time": "130911",
"data": {
"code": [ "TF1312", "TF1403", "TF1406" ],
"rt_time": [ 1.3091e+05, 1.3091e+05, 1.3091e+05 ]
}
},
"table2": {
"time": "130911",
"data": {
"contract": [ "TF1312", "TF1312", "TF1403" ],
"jtid": [ 99, 65, 21 ]
}
}
}
4). isValidJSON() 验证JSON是否正当
验证JSON的名目,是否正当。
> isValidJSON(json_str)
Error in file(con, "r") : cannot open the connection
> isValidJSON(json_str,TRUE)
[1] TRUE
> isValidJSON(I('{"foo" : "bar"}'))
[1] TRUE
> isValidJSON(I('{foo : "bar"}'))
[1] FALSE
4). 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 ],
[ 2, 5, 8, 11, 14 ],
[ 3, 6, 9, 12, 15 ] ] ;
获得JS两个变量,数组a和二维数组myMatrix.
3. 自界说JSON的实现
我们把R的data.frame工具转成我们界说的JSON名目。
下面JSON的界说名目
[
{
"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
}
]
R语言data.frame工具
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
code rt_time rt_latest rt_bid1 rt_ask1 rt_bsize1 rt_asize1 optionValue diffValue
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
#p#分页标题#e#
直接利用toJSON,输出的JSON串是按列组合成了数组,并不是我们想要的。
> 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 ]
}
对data.frame举办数据处理惩罚
library(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_time": "152929",
"rt_latest": 93.76,
"rt_bid1": 93.76,
"rt_ask1": 90.76,
"rt_bsize1": 1,
"rt_asize1": 11,
"optionValue": -0.1,
"diffValue": 0.5
}
]
这回就对了,正是我但愿的按行输出的功效!!通过alply函数做了调动。
4. JSON机能较量
机能较量我们做2组测试:
1). rjson和RJSONIO 对大工具举办序列化(toJSON)测试
建设一个rjson测试剧本,在呼吁行启动。
> library(rjson)
>
> df<-data.frame(
+ 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
> system.time(rjson::toJSON(df))
1.01 0.03 1.04
> system.time(rjson::toJSON(df))
0.98 0.05 1.03
同样,再建设一个RJSONIO测试剧本,在呼吁行启动。
> library(RJSONIO)
>
> df<-data.frame(
+ a=rep(letters,10000),
+ b=rnorm(260000),
+ c=as.factor(Sys.Date()-rep(1:260000))
+ )
>
> system.time(RJSONIO::toJSON(df))
2.23 0.02 2.24
> system.time(RJSONIO::toJSON(df))
2.30 0.00 2.29
> system.time(RJSONIO::toJSON(df))
2.25 0.01 2.26
比拟功效发明,rjson的机能优于RJSONIO。
2). rjson和RJSONIO,序列化(toJSON) 列式输出和行式输出的测试
建设一个rjson测试剧本,在呼吁行启动。
> library(rjson)
> library(plyr)
>
> df<-data.frame(
+ a=rep(letters,100),
+ b=rnorm(2600),
+ c=as.factor(Sys.Date()-rep(1:2600))
+ )
>
> system.time(rjson::toJSON(df))
0.01 0.00 0.02
> system.time(rjson::toJSON(df))
0.01 0.00 0.02
> system.time(rjson::toJSON(unname(alply(df, 1, identity))))
1.55 0.02 1.56
> system.time(rjson::toJSON(unname(alply(df, 1, identity))))
0.83 0.00 0.83
同样,再建设一个RJSONIO测试剧本,在呼吁行启动。
> library(RJSONIO)
> library(plyr)
>
> df<-data.frame(
+ a=rep(letters,100),
+ b=rnorm(2600),
+ c=as.factor(Sys.Date()-rep(1:2600))
+ )
>
> system.time(RJSONIO::toJSON(df))
0.03 0.00 0.03
> system.time(RJSONIO::toJSON(df))
0.04 0.00 0.03
> system.time(RJSONIO::toJSON(unname(alply(df, 1, identity))))
2.82 0.02 2.84
> system.time(RJSONIO::toJSON(unname(alply(df, 1, identity))))
2.06 0.00 2.06
通过测试我们发明,用toJSON直接列式输出,比行式输出要高效的多。同时,rjson要比RJSONIO高效。
转载请注明出处:
http://blog.fens.me/r-json-rjson/