R 是一种强大的语言,可用于内存中统计计算和图形显示。它类似于 SAS、IBM SPSS® Statistics、MATLAB 或 FORTRAN,但它是开源的。有一些转换器可以很容易地将以 SAS、IBM SPSS Statistics 或 MATLAB 格式保存的数据移动到 R。此外,R 配备了通过 Comprehensive R Archive Network (CRAN) 提供的大量软件包。CRAN 提供了一些功能,这些功能类似于针对 Perl 语言的 CPAN,或者针对 Ruby 语言的 Rubygems.org。R 还集成了 InfoSphere BigInsights(参见 参考资料)。
InfoSphere BigInsights 使用 JSON 格式来保存和显示数据,本文将介绍如何结合使用 JSON 与 R。JSON 是一个键值数据存储,可以直接映射到 JavaScript 对象。本文使用一组示例学生及其各自的考试成绩。
设置开发环境
首先,您需要设置开发环境。您需要使用 R,而且可以选择使用 RStudio 集成开发环境(IDE)。大多数软件包管理系统(apt、yum 等)默认情况下都提供了 R 版本 2.15,但是,如果想用最版的 R(在撰写本文时的最新版本是 3.0.2),则必须编辑您的可用数据源。
例如,要在 Debian 中编辑可用数据源,可以打开文件 /etc/apt/sources.list,并添加以下代码行:
- deb http://favorite-cran-mirror/bin/linux/debian wheezy-cran3/
用离您最近的镜像替换 favorite-cran-mirror。关于 CRAN 镜像的列表,请参见 参考资料。除了基于终端的 R 界面之外,您的 CRAN 镜像还为其他发行版本(比如 Red Hat Enterprise Linux®、SuSE 和 Ubuntu 等)提供了指令。
接下来,需要让 R 知道如何读取 JSON 数据。可以通过在 CRAN 上提供的 JSON for R (rjson) 软件包来读取数据。首先打开一个 R 终端。将软件包导入到本地 R 安装的语法是:
- install.packages("rjson")
然后使其可用:
- library("rjson")
您可以使用 CRAN 上提供的任何软件包的名称替换 rjson。
在 rjson 中,最基本的命令是 fromJSON() 和 toJSON()。本文只打算探索 fromJSON(),因为在与现有数据交互时,它是最有用的方法,现有数据包括 InfoSphere BigInsights 创建或解析的数据。
如果尚未下载示例文件 grades.json 并将其保存到一个可以访问的文件夹(参阅 下载),请先完成这一步。然后,用以下命令将文件导入 R:
- grades=fromJSON(file = '/path_to_file/grades.json', unexpected.escape = "error")
用您的文件路径替换 path_to_file。
标志 unexpected.escape 会告诉 rjson 如何处理意外的转义字符。该标志的选项是错误、保持和跳过。
基本的 R 命令
您可以在 R 中使用 help 函数了解关于任何给定命令的更多信息:
- help(name_of_command)
或者,您可以使用下面的命令:
- ?name_of_command
用您想学习的命令的名称替换 name_of_command。例如,想要阅读 library 命令的帮助页,只需输入 help(library)。这将打开 library 函数的帮助页。输入 q 会退出帮助页并返回 R shell。
在尝试使用其他语言(比如 Perl 或 Ruby)将数据导入 R 之前,请先清理数据,此操作通常对您很有益。有关的进一步说明已超出本文的讨论范围,但 R 提供了清理数据的工具。此外,rjson 包提供了一个标志来跳过未转义的特殊字符。sub() 和 gsub() 对于 R 是内部函数,它会根据正则表达式(regex)规则来修改数据。gsub 的语法如下:
- gsub(pattern, replacement, x, ignore.case = FALSE, perl = FALSE,
- fixed = FALSE, useBytes = FALSE)
例如,gsub("A", "a", grades) 在返回值中将每个大写的 A 转换为小写 a。perl 标志使得 R 使用 Perl 兼容的正则表达式库,而不是使用标准的正则表达式,如果想从 Perl 导入现有的正则表达式规则,可能会用到这个标志。
sub() 方法更改了匹配模式的第一次出现。而 gsub() 则更改了该模式的所有出现。
在 R 中提供的另一个有用的工具是 edit() 或 fix() 命令。有了它,您就可以编辑当前使用的数据集。例如,edit(grades) 打开第 R 对象 grades,这是本文前面所创建的对象。有了这个工具,您就可以动态修改数据。R 的默认编辑器为 vi 。如果想使用另一个编辑器,可以使用 options(editor = "nano") 更改它。用您选择的文本编辑器替代上面命令中的nano,例如,Pico 或 gedit。
此外,您可以通过使用 system() 命令,直接从 R 调用其他语言,该命令将会调用底层 shell 中的命令,并在 R 会话中打印出返回值。例如,system('echo "something"') 将会中断 R 会话,并将命令 echo "something" 传递给底层的 shell。然后,它会从标准输出(stdout)中抓取返回值(在本例中是单词 something),并让该值成为 R 会话中的返回值。下面的intern 标志可让返回值成为您可以操纵的 R 对象。
- system('echo "something"', intern=TRUE)
也许下面的命令是更有用的示例,该命令利用底层 shell 可用的任何语言的任意脚本中的返回值来创建 R 对象:
- system('./my/script/here.pl', intern=true)
R JSON 数据类型
要了解 R 如何处理 JSON 数据,首先应该从 rjson 库开始,它将导入列表格式的数据。要了解关于 R 数据类型的更多信息,请查看 参考资料中的链接。列表数据类型是最灵活的,因为它可以从列表数据分解成任何其他数据类型,而且列表类型中的数据不必是长度相等的(矢量类型则不同,存在这方面的限制。)不过,可以应用于数据集的许多统计函数都不能用于列表格式的数据。因此,您必须从列表格式的数据中将有用的数据点提取为另一种数据类型。
要探索 R 如何处理一段给定数据,可以使用命令 str()。如果使用了之前创建的 grades 对象,那么 str(grades) 的输出应该与清单 1 类似。
清单 1. 在 R 中的 JSON 数据的结构
- str(grades)
- List of 4
- $ :List of 4
- ..$ name : chr "Amy"
- ..$ grade1: num 35
- ..$ grade2: num 41
- ..$ grade3: num 53
- $ :List of 4
- ..$ name : chr "Bob"
- ..$ grade1: num 44
- ..$ grade2: num 37
- ..$ grade3: num 28
- $ :List of 4
- ..$ name : chr "Charles"
- ..$ grade1: num 68
- ..$ grade2: num 65
- ..$ grade3: num 61
- $ :List of 4
- ..$ name : chr "David"
- ..$ grade1: num 72
- ..$ grade2: num 78
- ..$ grade3: num 81
确定要提取哪些数据点,并使用 c(),或者使用联接,以便提取数据,如下所示:
- grade1.num <- c(grades[[1]]$grade1, grades[[2]]$grade1, grades[[3]]$grade1,
- grades[[4]]$grade1)
此命令函数将会创建一个新的对象 (grade1.num),其中包括每个学生第次考试的分数。grade1.num 现在是一个数值矢量,是 R 中最基本的数据类型。如果要删除 R 对象,那么可以发出 rm() 命令。例如,rm(grade1.num) 删除了刚刚从 R 会话创建的 grade1.num 对象。要为某个给定学生的成绩创建一个对象,可以发出以下命令:
- Amy.grade< - c(grades[[1]]$grade1, grades[[1]]$grade2, grades[[1]]$grade3)
该命令使用了赋值运算符,包括大于 (>) 或小于 (<) 符号,具体情况取决于赋值的方向,该命令还结合使用了一个连字符 (-)。通过索引号(例如,[[1]] 是第一个列表),或者通过带美元符号运算符的名称(例如,$grade1),访问以列表格式保存的项中的独立元素。
R 中更有用的一种数据类型是 data.frame,它是矢量的复合物。为了从示例数据创建 data.frame,首先需要为其余学生的分数创建数字矢量,如下所示:
- Bob.grade <- c(grades[[2]]$grade1, grades[[2]]$grade2, grades[[2]]$grade3)
- Charles.grade <- c(grades[[3]]$grade1, grades[[3]]$grade2, grades[[3]]$grade3)
- David.grade <- c(grades[[4]]$grade1, grades[[4]]$grade2, grades[[4]]$grade3)
接下来,用下面的命令将所有的矢量组合成一个数据帧:
- All.grades <- data.frame(Amy.grade, Bob.grade, Charles.grade, David.grade)
从逗号分隔值或电子表格程序导入 R 的数据也会成为 data.frame 对象,使用处理器内置到 R 中。