R和JSON的傻瓜式编程

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-json-rjson/

rjson

前言

JSON作为一种轻量级数据格式,被大量地应用在各种程序环境中。JSON(JavaScript Object Notation)是Javascript的内嵌的标准对象,同时也是MongoDB的表结构存储类型。JSON是半结构化的,可以表达出丰富的文档含义。JSON文档比XML文档要少很多,更适合于网络传输。

早期R语言编程很少会用到JSON,但随着R语言的壮大,R也在伸向各种领域,JSON就是与其他领域的一个交点。

如何让R语言傻瓜式花转JSON?请看正文介绍。

目录

  1. rjson包介绍
  2. RJSONIO包介绍
  3. 自定义JSON的实现
  4. toJSON性能比较: 我的测试结果rjson比RJSONIO更高效

1. rjson包介绍

rjson是一个R语言与json进行转的包,是一个非常简单的包,支持用 C类库转型和R语言本身转型两种方式。

rjson库,提供的函数只有3个,fromJSON(), newJSONParser(), toJSON()。 下面我们将介绍rjson库如何使用。

我的系统环境

  • Win7: x86_64-w64-mingw32/x64 (64-bit)
  • R: version 3.0.1 (2013-05-16)

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  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 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种方法:

  • 1. writeLines()
  • 2. sink()

# writeLines
> writeLines(json_str, "fin0_out1.json")

# sink
> sink("fin0_out2.json")
> cat(json_str)
> sink()

虽然写法不同,输出结果是一个样的,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  system.time( y2  system.time( y3 

我们可以看到,C库比R库会快,因为数据量很小,所以0.02并不明显。当JSON串很大的时候,这个差距就会变得相当的大了。

另外,fromJSON默认使用的C库的方法,所以我们平时处理不用加method='C'的参数。

toJSON的性能测试


> system.time( y  system.time( y2  system.time( y3 

同上的解释。

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  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 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 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

直接使用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)测试
  • 2. RJSONIO包,序列化(toJSON) 列式输出和行式输出的测试

1). rjson和RJSONIO 对大对象进行序列化(toJSON)测试
创建一个rjson测试脚本,在命令行启动。


> library(rjson)
>
> df
> 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
> 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
> 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
> 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/

打赏作者

This entry was posted in R语言实践

python+requests库接口自动化测试 Requests:是用python语言基于urllib编写的,采用的是Apache2Licensed开源协议的HTTP库,Requests它会比urllib更加方便,可以节约我们大量的工作。 阅读详情

相关推荐

Opencode傻瓜式接入DeepSeek:本地AI编码工作流实战指南

AI编码助手正从云端黑盒走向本地可集成的智能代理层。理解AI代理层(AI Agent Layer)的核心原理,即通过协议适配、工作流引擎与界面协调三层封装,将大模型调用抽象为声明式技能,显著降低开发者在VS Code中集成国产高性能模型(如DeepSeek-v4-pro)的技术摩擦。其技术价值在于屏蔽API差异、自动处理流式响应、内置限流降级与安全密钥管理,使模型真正融入代码解释、单元测试生成、Git提交信息编写等高频开发场景。本文聚焦Opencode这一典型实现,详解如何零配置完成DeepSeek千帆AP

weixin_34180452的博客 371

R语言教程:使用R读取JSON文件并转换为数据框

记住,在使用R处理JSON数据之前,确保安装并加载了适当的包(如"jsonliteSON数据之前,确保安装并加载了适当的包(如"jsonlite""dplyr"),以便能够使用相关的函数工具。本教程将向您展示如何使用R语言读取JSON文件,并将其转换为数据框(data frame)的形式,以便进行后续的数据分析处理。首先,我们需要安装加载几个在R中处理JSON文件时常用的包,包括"jsonlite""dplyr"。通过使用类似上述的操作,您可以根据自己的需求对数据框进行进一步的处理分析。

ByteJolt的博客 1115

sqlmap -r参数实战指南:从HTTP请求文件到精准注入检测

本文详细介绍了sqlmap中-r参数的使用方法,作为处理复杂HTTP请求的“懒人神器”。通过实战演示,指导用户如何从捕获请求、制作标准请求文件,到进行精准注入检测数据库脱裤。文章重点讲解了如何应对登录态、JSON/XML请求、动态Token等高级场景,并提供了自动化集成与常见错误排查方案,帮助安全测试人员高效完成授权下的漏洞检测工作。

weixin_29323493的博客 221

POST方法使用之响应数据r.json()与r.text区别

响应数据json()与text()区别 json():返回类型为字典,可以通过键名来获取响应的值 text():返回的类型为字符串,无法通过键名来获取响应的值 提示:共同点长得都像字典 #1.导包 import requests import json #2.调用post #请求url url="https://10.65.*.*/api/*/*/auth/login/" #请求headers headers={ "Content-Type":"application/json" }

weixin_45878889的博客 3290

python 中json使用方法

Json简介:Json,全名 JavaScript Object Notation,是一种轻量级的数据交换格式。Json最广泛的应用是作为AJAX中web服务器客户端的通讯的数据格式。现在也常用于http请求中,所以对json的各种学习,是自然而然的事情。Python的官网网址:https://docs.python.org/2/library/json.html?highlight=json#m

zhongmincsdn的博客 689

r.json()

requests模块中,r.json()为Requests中内置的JSON解码器 其中只有response返回为json格式时,用r.json()打印出响应的内容, 如果response返回不为json格式,使用r.json()会报错 报错内容:ValueError:Expectingpropertynameenclosedindoublequotes:line1c...

weixin_30245867的博客 2534

《R的极客理想—工具篇》—— 1.6 RJSON傻瓜式编程

本节书摘来自华章出版社《R的极客理想—工具篇》一 书中的第1章,第1.6节,作者:张丹,更多章节内容可以访问云栖社区“华章计算机”公众号查看。 1.6 RJSON傻瓜式编程 问题如何让R语言的数据类型转换成JSON数据类型? 引言JSON作为一种轻量级数据格式,被大量地应用在各种程序环境中。JSON(JavaScript Object Notatio...

weixin_33981932的博客 257

R的极客理想系列文章

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习体验去诠释R的强大。 R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。 要成为有理想的极客,我们不能停留在语法上,要

闲云孤鹤 1万+

Json-server 的使用教程

可以让前端人员不用去编写后端的代码,就能在本地搭建一个json服务,可用于测试一些业务逻辑,便于调试调用。在前后端分离的开发模式下前端使用模拟数据接口, 这时候 后端接口还没有开发出来, 前端又需要数据进行开发,这种情况下就需要前端先行模拟数据, 等后端接口写好进行targetUrl进行替换。github 地址npm 地址是一个零代码快速搭建本地使用JSON文件作为数据源,通过提供一组简单的路由端点来模拟后端服务器的行为它允许前端开发人员在不依赖后端API的情况下进行开发,通过本地搭建一个JSON

xhmico的博客 8755

好用的接口测试工具---PostMan

后端程序员必备的的PostMan

Java全栈领域/离线地图/微服务 6652

R的极客理想系列文章[转自http://blog.fens.me/series-r/]

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34218579的博客 130

使用R的networkD3包画可交互的网络图

d3network包 http://www.cnblogs.com/shangfr/p/5417054.html ShangFR 2016年5月6日 R d3network包 力导向图 桑基图(Sankeydiagram) Reingold-Tilford树型图 反馈与建议 R d3network包 通过Christopher Gandru...

aniuzaixian_2017的博客 712

Rserve详解,R语言客户端RSclient【转】

R语言服务器程序 Rserve详解 http://blog.fens.me/r-rserve-server/ Rserve的R语言客户端RSclient https://blog.csdn.net/u011955252/article/details/65442783 http://blog.fens.me/series-r/ R的极客理想系列文章 R的极客理想系列文...

weixin_34321977的博客 168

配置VSCode 不闪退 不乱码的C语言外部控制台——傻瓜式操作指南

根据本文步骤操作,可实现vscode 不闪退 无中文乱码 的外部控制台输出

weixin_51292258的博客 2955

OpenClaw傻瓜式部署指南:Docker本地/阿里云生产/边缘协同三法

OpenClaw是一种轻量级、离线可用的自动化技能执行引擎,核心原理是通过命令行驱动可插拔的‘技能链’(Skill Chain),实现上下文感知的任务编排。其技术价值在于降低AI工作流落地门槛——无需可视化平台、不依赖中心化服务,但对运行时环境高度敏感。典型应用场景包括本地PDF处理与大模型摘要、云服务器上的团队共享技能服务、以及路由器等边缘设备触发的IoT自动化任务。实际部署中,环境一致性、依赖服务协同(如Nacos/Redis)、云厂商网络策略(如阿里云安全组出向限制、腾讯云IAM权限)构成主要挑战。本

weixin_34319374的博客 353

Rxjava2+Retrofit2网络框架傻瓜式接入指南

前言 本文主要是介绍本人在项目中接入Rxjava2Retrofit2的过程中的一些经验心得、遇到的问题,特别是本人的学习曲线,希望能帮助到你。主要的概念介绍涉及较少,但是在文中会给出我在接入的过程中参考过的文章。 之所以把Rxjava2放在前面是因为,我最开始的时候只想接入Rxjava2来体验高大上的响应式编程,但是在学习接入Rxjava2的过程中,感觉到非常有必要将Retrofit也

袁科的博客 3399

DeepSeek-R1-Distill-Qwen-1.5B应用案例:农业技术推广员方言问答知识库构建

本文介绍了如何在星图GPU平台上自动化部署🐋 DeepSeek-R1-Distill-Qwen-1.5B 本地智能对话助手 (Streamlit 驱动) 镜像,构建面向基层农技推广员的方言问答知识库,支持离线环境下用乡土语言快速获取精准农业技术指导,切实解决农业科技落地‘最后一公里’问题。

ThunderstormDragon65的博客 405
上一篇: Nodejs异步流程控制Async
下一篇: RequireJS异步模块加载
Fens
博客等级 码龄25年 126粉丝 277原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值