1 R语言介绍
一个典型的数据分析过程如下,是一个需要不断迭代和修正的过程。
1.1 为何要使用R?
R有着非常多值得推荐的特性:
- 多数商业统计软件价格不菲,投入成千上万美元都是可能的。而R是免费的!如果你是一位教师或一名学生,好处显而易见;
- R是一个全面的统计研究平台,提供了各式各样的数据分析技术;
- R拥有顶尖水准的制图功能;
- R是一个可进行交互式数据分析和探索的强大平台,其核心设计理念就是支持上图中所概述的分析方法;
- R可以轻松地从各种类型的数据源导入数据,包括文本文件、数据库管理系统、统计软件,乃至专门的数据仓库;
- R可运行于多种平台之上,包括Windows、UNIX和Mac OS X。
总的来说,R能够让你以一种简单而直接的方式创建优雅、信息丰富、高度定制化的图形。而使用其他统计语言创建类似的图形不仅费时费力,而且可能根本无法做到。
1.2 R的获取和安装
R可以在CRAN上下载并安装,提供了Windows、UNIX和Mac OX等各大平台的安装版本。之后还将介绍如何安装增强R功能的可选模块——包(package)。
1.3 R的使用
R是一种区分大小写的解释型语言,你可以在命令提示符(>)后每次输入并执行一条命令,或者一次性运行在脚本中写好的多条命令。
R的多数功能由程序内置函数和用户自编函数提供(如果你用过python、matlab之类,这里应该很好理解)。一些函数是默认可用的,其他高级函数需要按需加载相应的模块。
R使用<-赋值,而不是传统的=,例如:
创建了一个名为x的向量对象,包含5个来自标准正态分布的随机偏差。
在R中,注释由符号#开头。
一个简单的例子
可以使用函数c()以向量的形式赋值,并使用内置的统计函数计算统计值,然后用图形展示,最后使用q()退出R。来一个计算婴儿月龄和体重数据的例子吧!
|
age
<
-
c
(
1
,
3
,
5
,
2
,
11
,
9
,
3
,
9
,
12
,
3
)
weight
<
-
c
(
4.4
,
5.3
,
7.2
,
5.2
,
8.5
,
7.3
,
6.0
,
10.4
,
10.2
,
6.1
)
mean
(
weight
)
[
1
]
7.06
sd
(
weight
)
[
1
]
2.077498
cor
(
age
,
weight
)
[
1
]
0.9075655
plot
(
age
,
weight
)
q
(
)
|
再附上几个R绘图demo命令:demo(graphics)、demo(Hershey)、demo(persp)、demo(image)。查看完整的演示列表,直接运行demo()。
获取帮助
当你需要帮助时,不妨使用以下命令:
- help.start():打开帮助文档首页;
- help(“foo”)或?foo:查看函数foo的帮助(引号可以省略);
- help.search(“foo”)或??foo:以foo为关键词搜索本地帮助文档;
- example(“foo”):函数foo的使用示例(引号可以省略);
- RSiteSearch(“foo”):以foo为关键词搜索在线文档和邮件列表存档;
- apropos(“foo”, mode=”function”):列出名称中含有foo的所有可用函数;
- data():列出当前已加载包中所含的所有可用示例数据集;
- vignette():列出当前已安装包中所有可用的vignette文档;
- vignette(“foo”):为主题foo显示指定的vignette文档。
工作空间
工作空间就是当前R的工作环境,它储存着所有用户定义的对象(向量、矩阵、函数、数据框、列表),你可以保存和载入工作空间。交互过程的历史命令也保存于工作空间中,可以使用上下方向键查看,用return来重复执行上条命令。
一些和工作空间相关的函数:
- getwd():显示当前的工作目录;
- setwd(“mydirectory”):修改当前的工作目录为mydirectory;
- ls():列出当前工作空间中的对象;
- rm(objectlist):移除(删除)一个或多个对象;
- help(options):显示可用选项的说明;
- options():显示或设置当前选项;
- history(#):显示最近使用过的#个命令(默认值为25);
- savehistory(“myfile”):保存命令历史到文件myfile中(默认值为.Rhistory);
- loadhistory(“myfile”):载入一个命令历史文件(默认值为.Rhistory);
- save.image(“myfile”):保存工作空间到文件myfile中(默认值为.RData);
- save(objectlist, file=”myfile”):保存指定对象到一个文件中;
- load(“myfile”):读取一个工作空间到当前会话中(默认值为.RData);
- q():退出R,将会询问你是否保存工作空间。
输入和输出
如果需要运行一个R脚本中的多行命令该如何操作?R使用source(“filename”)载入脚本,使用sink(“filename”)将结果输出到文档中。其中后者可以加参数,append=TRUE表明将输出文本追加到文件后而不是覆盖,split=TRUE可将输出同时发送到屏幕和输出文本中,不加参数调用sink()将仅向屏幕返回输出结果。
图形输出的话,可使用以下函数输出成相应文件:pdf(“filename.pdf”)、win.metafile(“filename.wmf”)、png(“filename.png”)、jpeg(“filename.jpg”)、bmp(“filename.bmp”)、postscript(“filename.ps”),最后使用dev.off()将输出返回至终端。
总而言之,屏幕是默认的文本和图像输出端,但是也可以指定输出至文件。
1.4 包
包是R的可选扩展功能模块,官方提供的2500多个包横跨各种领域、功能惊人,包括分析地理数据、处理蛋白质质谱,甚至是心理测验分析的功能。
.libPath()函数可以查看R中已安装的包集合(称为库)的路径,函数library()可以显示库中有哪些包,函数search()可以得到哪些包已经被加载并可以使用。
包的安装
install.packages(),不带参数则返回一个CRAN镜像站点列表,带参数即包名则直接安装。
一个包只需要安装一个,包若有更新,则使用update.packages(“packagename”)进行更新。
使用installed.packages()查看已经安装的包及描述。
包的载入
使用library(packagename)以载入包,一次会话中只需要加载一次。当然也可以自定义启动环境,以自定义默认加载的包。
包的使用
加载了包之后,使用help(package=”packagename”)来查看该包的帮助信息,包括函数名称和数据集列表。
1.5 批处理
如果希望不是交互地运行R,而是周期地重复运行R文件,该如何做呢?
Linux或Mac OS下:
|
R
CMD
BATCH
options
infile
outfile
|
其中infile为包含要执行R代码的文件名,扩展名为.R,outfile为接收输出文件名,扩展名为.Rout,options列出了控制执行细节的选项。
1.6 实战
完成以下操作吧!
- 打开帮助文档首页,并查阅其中的“Introduction to R”;
- 安装vcd包(一个用于可视化类别数据的包);
- 列出此包中可用的函数和数据集;
- 载入这个包并阅读数据集Arthritis的描述;
- 显示数据集Arthritis的内容(直接输入一个对象的名称将列出它的内容);
- 运行数据集Arthritis自带的示例;
- 退出。
所需代码:
|
help
.
start
(
)
install
.
packages
(
"vcd"
)
help
(
package
=
"vcd"
)
library
(
vcd
)
help
(
Arthritis
)
Arthritis
example
(
Arthritis
)
q
(
)
|
2 创建数据集
数据分析 BY 伦大锤 阅读量 1,338
按照个人要求的格式来创建含有研究信息的数据集,这是任何数据分析的第一步。在R中,这个任务包括以下两步:
- 选择一种数据结构来存储数据;
- 将数据输入或导入到这个数据结构中。
2.1 数据结构
R拥有许多用于存储数据的对象类型,包括标量、向量、矩阵、数组、数据框和列表,其中一部分数据类型可以用下图来说明:
向量
向量是用于存储数值型、字符型或逻辑型数据的一维数组,单个向量中的数据必须拥有相同的类型或模式。
|
a
<
-
c
(
1
,
2
,
5
,
3
,
6
,
-
2
,
4
)
b
<
-
c
(
"one"
,
"two"
,
"three"
)
c
<
-
c
(
TRUE
,
TRUE
,
TRUE
,
FALSE
,
TRUE
,
FALSE
)
|
用方括号访问向量中的元素,如访问向量a中的第二个和第四个元素:
支持冒号语法,以下将返回a的第二至第六个元素:
矩阵
矩阵是一个二维数组,每个元素都拥有相同的模式(数值型、字符型或逻辑型)。可通过函数matrix创建矩阵。
|
mymatrix
<
-
matrix
(
vector
,
nrow
=
number_of_rows
,
ncol
=
number_of_columns
,
byrow
=
FALSE
,
dimnames
=
list
(
rownames
,
colnames
)
)
|
其中vector向量包含了矩阵元素,nrow和ncol为行数和列数,byrow默认为FALSE表示按列填充,否则TRUE为按行填充,dimnames为行列名。使用时,只有前三个参数是必须的。
|
y
<
-
matrix
(
1
:
20
,
nrow
=
5
,
ncol
=
4
)
cell
<
-
c
(
1
,
26
,
24
,
68
)
rnames
<
-
c
(
"R1"
,
"R2"
)
cnames
<
-
c
(
"C1"
,
"C2"
)
mymatrix
<
-
matrix
(
cell
,
nrow
=
2
,
ncol
=
2
,
byrow
=
TRUE
,
dimnames
=
list
(
rnames
,
cnames
)
)
mymatrix
<
-
matrix
(
cell
,
nrow
=
2
,
ncol
=
2
,
byrow
=
FALSE
,
dimnames
=
list
(
rnames
,
cnames
)
)
|
x[i,]表示矩阵x中的第i行,x[,j]表示矩阵x中的第j列,x[i,j]表示矩阵x中的第i行第j个元素,或者使用数值型向量代替i、j以选择多行或多列。
数组
数组和矩阵类似,但是维度可以大于2,通过array函数创建。
|
myarray
<
-
array
(
vector
,
dimensions
,
dimnames
)
|
其中vector包含数组中的数据,dimensions是一个数值型向量,给出了各个维度下标的最大值,dimnames可选、表示各维度名称标签的列表。
|
dim1
<
-
c
(
"A1"
,
"A2"
)
dim2
<
-
c
(
"B1"
,
"B2"
,
"B3"
)
dim3
<
-
c
(
"C1"
,
"C2"
,
"C3"
,
"C4"
)
z
<
-
array
(
1
:
24
,
c
(
2
,
3
,
4
)
,
dimnames
=
list
(
dim1
,
dim2
,
dim3
)
)
|
数据框
可以理解成数据库中的表,特点是不同的列可以包含不同模式(数值型、字符型等)数据,但是每列的数据模式必须相同,通过data.frame创建。
|
patientID
<
-
c
(
1
,
2
,
3
,
4
)
age
<
-
c
(
25
,
34
,
28
,
52
)
diabetes
<
-
c
(
"Type1"
,
"Type2"
,
"Type1"
,
"Type1"
)
status
<
-
c
(
"Poor"
,
"Improved"
,
"Excellent"
,
"Poor"
)
patientdata
<
-
data
.
frame
(
patientID
,
age
,
diabetes
,
status
)
|
访问数据可以通过以下三种方式:
|
patientdata
[
1
:
2
]
patientdata
[
c
(
"diabetes"
,
"status"
)
]
patientdata
$
age
|
如果希望生成diabetes和status的列联表,使用以下代码即可:
|
table
(
patientdata
$
diabetes
,
patientdata
$
status
)
|
可以使用attach()和detach()将数据框添加至R搜索路径或移除:
|
attach
(
patientdata
)
summary
(
status
)
detach
(
patientdata
)
|
很好理解,添加到R搜索路径之后,就可以直接用列名访问数据框中的列了。考虑到命名冲突的问题,函数attach()和detach()最好在分析一个单独的数据框,并且不太可能有多个同名对象时使用。任何情况下,都要当心那些告知某个对象已被屏蔽(masked)的警告,意味着之后以这些名称命名的变量将被屏蔽。
除此之外,还可以使用with()函数:
|
with
(
patientdata
,
{
summary
(
status
)
}
)
|
由于大括号{}之间的语句都针对patientdata执行,所以不存在命名冲突的问题。主要注意的是,如果在大括号里面进行了变量赋值操作,在大括号外面讲无法访问该变量,除非是用特殊赋值符<<-。不妨试试以下代码,temp仅能在大括号内部访问,perm则可以在外部访问。
|
with
(
patientdata
,
{
temp
<
-
summary
(
status
)
perm
<<
-
summary
(
status
)
temp
}
)
temp
perm
|
另外,可以使用row.names指定数据框的实例标识符(差不多就是主键的意思吧)。
因子
类别(名义型)变量和有序类别(有序型)变量在R中称为因子(factor)。因子在R中非常重要,因为它决定了数据的分析方式以及如何进行视觉呈现。
对于类别值,函数factor将其映射为整数:
|
diabetes
<
-
factor
(
c
(
"Type1"
,
"Type2"
,
"Type1"
,
"Type1"
)
)
|
其将Type1映射为1、Type2映射为2。
对于有序型,函数factor将其按字母顺序映射(需要增加参数ordered=TRUE表明当前处理的为有序型变量):
|
status
<
-
factor
(
c
(
"Poor"
,
"Improved"
,
"Excellent"
,
"Poor"
)
,
ordered
=
TRUE
)
|
其将Excellent映射为1、Improved映射为2、Poor映射为3。
可以使用level来指定有序型的顺序:
|
status
<
-
factor
(
c
(
"Poor"
,
"Improved"
,
"Excellent"
,
"Poor"
)
,
ordered
=
TRUE
,
levels
=
c
(
"Poor"
,
"Improved"
,
"Excellent"
)
)
|
其将Poor映射为1、Improved映射为2、Excellent映射为3。
列表
列表的每个元素可以是以上提及的任何数据类型,甚至其他列表的组合,使用list定义,可以为各个元素命名:
|
g
<
-
"My First List"
h
<
-
c
(
25
,
26
,
18
,
39
)
j
<
-
matrix
(
1
:
10
,
nrow
=
5
)
k
<
-
c
(
"one"
,
"two"
,
"three"
)
mylist
<
-
list
(
title
=
g
,
ages
=
h
,
j
,
k
)
mylist
|
可以看到mylist包括四个元素,使用mylist[[2]]或者mylist[[“ages”]]访问第二个元素。
2.2 数据的输入
R可从键盘、文本文件、Microsoft Excel和Access、流行的统计软件、特殊格式的文件,以及多种关系型数据库中导入数据 。
使用键盘输入数据
可以使用键盘编辑变量的值:
- 创建一个空数据框(或矩阵),其中变量名和变量的模式需与理想中的最终数据集一致;
- 针对这个数据对象调用文本编辑器,输入你的数据,将结果保存回此数据对象中。
使用以下代码来手动编辑一个变量:
|
mydata
<
-
data
.
frame
(
age
=
numeric
(
0
)
,
gender
=
character
(
0
)
,
weight
=
numeric
(
0
)
)
mydata
<
-
edit
(
mydata
)
|
其中类似age=numeric(0)的赋值语句将创建一个指定模式但不包含实际数据的变量。注意,最后编辑的结果需要赋值回对象本身,否则所有修改将无法生效。
从带分隔符的文本文件导入数据
可以使用read.table()从带分隔符的文本文件中导入数据,该函数可读入一个表格格式的文件并将其保存为一个数据框:
|
mydatafram
<
-
read
.
table
(
file
,
header
=
logical_value
,
sep
=
"delimiter"
,
row
.
names
=
"name"
)
|
file为一个带分隔符的ASCII文本文件,header表明首行是否包含变量名,sep表示分隔符,row.names可选,用以指定一个或多个表示行标识符的变量即主键,例如:
|
grades
<
-
read
.
table
(
"studentgrades.csv"
,
header
=
TRUE
,
sep
=
","
,
row
.
names
=
"STUDENTID"
)
|
查看关于更多微调数据导入方式的追加选项,请参阅help(read.table)。
导入Excel数据
读取一个Excel文件的最好方式,就是在Excel中将其导出为CSV(逗号分隔文件)。
如有兴趣,在Windows上也可以研究如下包:RODBC和xlsx。
导入XML数据
R中有若干用于处理XML文件的包,例如由Duncan Temple Lang编写的XML包允许用户读取、写入和操作XML文件。XML格式本身已经超出了本书的范围,有兴趣的话可以参阅www.omegahat.org/RSXML,从中可以找到若干份优秀的软件包文档。
从网页抓取数据
主要是通过readLines()函数下载网页,然后使用如grep()和gsub()一类的函数处理。对于结构复杂的网页,可以使用RCurl包和XML包来提取其中想要的信息。更多信息和实例请参考Programming with R上的“Webscraping using readLines and RCurl”一文。
导入SPSS数据
SPSS数据集可以通过foreign包中的read.spss()或Hmisc包中的spss.get()函数:
|
install
.
packages
(
"Hmisc"
)
library
(
Hmisc
)
mydataframe
<
-
spss
.
get
(
"mydata.sav"
,
use
.
value
.
labels
=
TRUE
)
|
use.value.labels=TRUE表示让该函数将带有值标签的变量导入为R中水平对应相同的因子。
导入SAS数据
SAS数据集可以使用foreign包中的read.ssd()和Hmisc包中的sas.get(),或者在SAS中首先将数据导出为CSV。
导入Stata数据
要将Stata数据导入R中非常直接简单:
|
library
(
foreign
)
mydataframe
<
-
read
.
dta
(
"mydata.dta"
)
|
访问数据库管理系统
R中有多种面向关系型数据库管理系统的接口,包括Microsoft SQL Server、Microsoft Access、MySQL、Oracle、PostgreSQL、DB2、Sybase、Teradata以、SQLite。
在R中通过RODBC包访问一个数据库也许是最流行的方式,这种方式允许R连接到任意一种拥有ODBC驱动的数据库。
第一步是针对你的系统和数据库类型安装和配置合适的ODBC驱动,第二步则是安装ODBC包,即install.packages(“RODBC”)。
RODBC包中的主要函数有:
- odbcConnect(dsn,uid=””,pwd=””):建立一个到ODBC数据库的连接;
- sqlFetch(channel,sqltable):读取ODBC数据库中的某个表到一个数据框中;
- sqlQuery(channel,query):向ODBC数据库提交一个查询并返回结果;
- sqlSave(channel,mydf,tablename=sqtable,append=FALSE):将数据框写入或更新(append=TRUE)到ODBC数据库的某个表中;
- sqlDrop(channel,sqtable):删除某个表;
- close(channel):关闭连接。
2.3 数据集的标注
为了使结果更易于解读,数据分析人员通常会对数据集进行标注。标注包括为变量名添加描述性的标签,以及为类别型变量中的编码添加值标签。
变量标签
例如,对于变量age,你可能想附加一个描述更详细的标签,“Age at hospitalization (in years)”,但是目前R对变量标签的支持能力十分有限。
值标签
函数factor()可以为类别型变量创建值标签:
|
patientdata
$
gender
<
-
factor
(
patientdata
$
gender
,
levels
=
c
(
1
,
2
)
,
levels
=
c
(
"male"
,
"female"
)
)
|
2.4 处理数据对象的实用函数
- length():显示对象中元素/成分的数量;
- dim(object):显示对象的维度;
- str(object):显示对象的结构;
- class(object):显示对象的类或类型;
- mode(object):显示对象的模式;
- names(object):显示对象中各成分的名称;
- c(object, object,…):将对象合并成向量;
- cbind(object, object, …):按列合并对象;
- rbind(object, object, …):按行合并对象;
- Object:输出某个对象;
- head(object):列出对象的前六个元素;
- tail(object):列出对象的后六个元素;
- ls():显示当前的对象列表;
- rm(object, object, …):删除一个或多个对象,rm(list=ls())将删除当前工作空间中的几乎所有对象;
- newobject <- edit(object):编辑对象并另存为newobject;
- fix(object):直接编辑对象。
3 图形初阶
数据分析 BY 伦大锤 阅读量 865
R最大的魅力在于其强大的图形绘制功能。“一图胜千言”,有时候数字和文字费劲心力展示出来的结果,往往不如一副恰到好处的图形来得清楚。更重要的是,有些模式和异常往往只有通过图形才能被人类所捕捉。
3.1 使用图形
来个简单的例子吧:
|
wt
<
-
c
(
10
,
12
,
15
,
18
)
mpg
<
-
c
(
30
,
35
,
46
,
57
)
mtcars
<
-
data
.
frame
(
wt
,
mpg
)
attach
(
mtcars
)
plot
(
wt
,
mpg
)
abline
(
lm
(
mpg
~
wt
)
)
title
(
"Regression of MPG on Weight"
)
detach
(
mtcars
)
|
其中第六行代码用于生成一条最优拟合曲线。
如果需要保存图形,可以通过GUI操作,或者在代码中进行,将和绘图有关的代码加在开启目标图形设备语句和关闭目标设备语句之间即可:
|
pdf
(
"mygraph.pdf"
)
attach
(
mtcars
)
plot
(
wt
,
mpg
)
abline
(
lm
(
mpg
~
wt
)
)
title
(
"Regression of MPG on Weight"
)
detach
(
mtcars
)
dev
.
off
(
)
|
除了pdf()外,还可以使用函数win.metafile()、png()、jpeg()、bmp()、tiff()、xfig()和postscript()将图形保存为其他格式。
3.2 一个简单的例子
基于以下数据,我们来走一遍R绘图涉及到的基本操作。以下数据描述了病人对两种药物五个剂量水平上的响应情况。
首先输入数据:
|
dose
<
-
c
(
20
,
30
,
40
,
45
,
60
)
drugA
<
-
c
(
16
,
20
,
27
,
40
,
60
)
drugB
<
-
c
(
15
,
18
,
25
,
31
,
40
)
|
使用以下代码创建一副描述药物A的剂量和响应关系的图形:
|
plot
(
dose
,
drugA
,
type
=
"b"
)
|
其中type=”b”表示同时绘制点和线,使用help(plot)可以查看其他帮助选项。
3.3 图形参数
可以通过修改称为图形参数的选项来自定义一副图形的多个特征(字体、颜色、坐标轴、标题)。一种方法是通过par()来指定这些选项,修改会一直维持到此次会话结束前有效。
|
opar
<
-
par
(
no
.
readonly
=
TRUE
)
par
(
lty
=
2
,
pch
=
17
)
plot
(
dose
,
drugA
,
type
=
"b"
)
par
(
opar
)
|
第一行代码将当前可修改的图形参数复制了一份,第二行代码修改线型和点型,第三行代码绘图(你可以看到默认的实线变成了虚线,空心点变成了三角形),第四行还原了默认图形参数。
当然,也可以在绘图函数中直接包括图形参数,该参数仅对当前绘图有效:
|
plot
(
dose
,
drugA
,
type
=
"b"
,
lty
=
2
,
pch
=
17
)
|
符号和线条
绘图时使用的符号和线条类型包括:
- pch:绘制点时使用的符号;
- cex:指定符号的大小,填相对值,1为默认;
- lty:线条类型;
- lwd:线条宽度,填相对值,1为默认。
pch可选的选项:
对于符号21~25,还可以指定边界颜色(col=)和填充色(bg=)。
lty可选的选项:
颜色
R中常用的和颜色相关的参数包括:
- col:默认的绘图颜色;
- col.axis:坐标轴刻度文字的颜色;
- col.lab:坐标轴标签的颜色;
- col.main:标题颜色;
- col.sub:副标题的颜色;
- fg:图形的前景色;
- bg:图形的背景色。
在R中,可以使用颜色下标、颜色名称、十六进制颜色值、RGB值或HSV值来指定颜色,例如,col=1、col=”white”、col=”#FFFFFF”、col=rgb(1,1,1)、col=hsv(0,0,1)都是表示白色的等价方式。
函数colors()可以返回所有可用颜色的名称。R中也有多种用于创建连续型颜色向量的函数,包括rainbow()、heat.colors()、terrain.colors()、topo.colors()以及cm.colors()。例如,rainbow(10)可以生成10种连续的“彩虹型”颜色,gray(0:10/10)将生成10阶灰度色。不妨试试以下代码:
|
n
<
-
10
mycolors
<
-
rainbow
(
n
)
pie
(
rep
(
1
,
n
)
,
labels
=
mycolors
,
col
=
mycolors
)
mygrays
<
-
gray
(
0
:
n
/
n
)
pie
(
rep
(
1
,
n
)
,
labels
=
mygrays
,
col
=
mygrays
)
|
文本属性
图形参数同样可以用来指定字号、字体和字样。
- cex:指定相对缩放倍数,默认为1;
- cex.axis:坐标轴刻度文字的缩放倍数;
- cex.lab:坐标轴标签的缩放倍数;
- cex.main:标题的缩放倍数;
- cex.sub:副标题的缩放倍数。
以下则是指定字体、字号和字样的参数:
图形尺寸和边界尺寸
使用以下三个函数来指定图形大小和边距:
- pin:以英寸表示的图形尺寸(宽和高);
- mai:以数值向量表示的边界大小,顺序为“下左上右”,单位为英寸;
- mar:以数值向量表示的边界大小,顺序为“下左上右”,单位为英分,一英寸为十二英分。
3.4 添加文本、自定义坐标轴和图例
许多高级绘图函数(例如plot、hist、boxplot)也允许自行设定坐标轴和文本标注选项。以下代码在图形上添加了标题(main)、副标题(sub)、坐标轴标签(xlab、ylab)并指定了坐标轴范围(xlim、ylim)。
|
plot
(
dose
,
drugA
,
type
=
"b"
,
col
=
"red"
,
lty
=
2
,
pch
=
2
,
lwd
=
2
,
main
=
"Clinical Trials for Drug A"
,
sub
=
"This is hypothetical data"
,
xlab
=
"Dosage"
,
ylab
=
"Drug Response"
,
xlim
=
c
(
0
,
60
)
,
ylim
=
c
(
0
,
70
)
)
|
某些高级绘图函数已经包含了默认的标题和标签,可以通过在plot()语句或单独的par()语句中添加ann=FALSE来移除他们。
标题
可以使用title()函数为图形添加标题和坐标轴标签:
|
title
(
main
=
"main title"
,
sub
=
"sub-title"
,
xlab
=
"x-axis label"
,
ylab
=
"y-axis label"
)
|
函数title()中还可以指定其他图形参数,如文本大小、字体、旋转角度和颜色。
|
title
(
main
=
"My Title"
,
col
.
main
=
"red"
,
sub
=
"My Sub-title"
,
col
.
sub
=
"blue"
,
xlab
=
"My X label"
,
ylab
=
"My Y label"
,
col
.
lab
=
"green"
,
cex
.
lab
=
0.75
)
|
坐标轴
可以使用axis()来创建自定义的坐标轴:
|
axis
(
side
,
at
=
,
labels
=
,
pos
=
,
lty
=
,
col
=
,
las
=
,
tck
=
,
.
.
.
)
|
各参数含义如下:
创建自定义坐标轴时,需要禁用高级绘图函数自动生成的坐标轴。参数axes=FALSE将禁用全部坐标轴(包括坐标轴框架线),参数xaxt=”n”和yaxt=”n”将分别禁用X轴和Y轴(除去刻度,仍留下框架线)。来一个稍显复杂的例子:
1
2
3
4
5
6
7
8
9
10
11
12
|
x
<
-
c
(
1
:
10
)
y
<
-
x
z
<
-
10
/
x
opar
<
-
par
(
no
.
readonly
=
TRUE
)
par
(
mar
=
c
(
5
,
4
,
4
,
8
)
+
0.1
)
plot
(
x
,
y
,
type
=
"b"
,
pch
=
21
,
col
=
"red"
,
yaxt
=
"n"
,
lty
=
3
,
ann
=
FALSE
)
lines
(
x
,
z
,
type
=
"b"
,
pch
=
22
,
col
=
"blue"
,
lty
=
2
)
axis
(
2
,
at
=
x
,
labels
=
x
,
col
.
axis
=
"red"
,
las
=
2
)
axis
(
4
,
at
=
z
,
labels
=
round
(
z
,
digit
=
2
)
,
col
.
axis
=
"blue"
,
las
=
2
,
cex
.
axis
=
0.7
,
tck
=
-
.
01
)
mtext
(
"y=10/x"
,
side
=
4
,
line
=
3
,
cex
.
lab
=
1
,
las
=
2
,
col
=
"blue"
)
title
(
"An Example of Creatice Axes"
,
xlab
=
"X Value"
,
ylab
=
"Y=X"
)
par
(
opar
)
|
函数mtext()用于在图形的边界添加文本,lines()可以为一副现有图形添加新的图形元素。
至于次刻度线,需要使用Hmisc包中的minor.tick()函数:
|
library
(
Hmisc
)
minor
.
tick
(
nx
=
n
,
ny
=
n
,
tick
.
ratio
=
n
)
|
例如以下代码在X轴每两条主刻度线中添加一条次刻度线、在Y轴每两条主刻度线中添加两条次刻度线,次刻度线的长度为主刻度线的一半。
|
minor
.
tick
(
nx
=
2
,
ny
=
3
,
tick
.
ratio
=
0.5
)
|
参考线
函数abline()可以用来为图形添加参考线:
|
abline
(
h
=
yvalues
,
v
=
xvalues
)
|
在y为1、5、7的位置添加水平实线:
|
abline
(
h
=
c
(
1
,
5
,
7
)
)
|
在x为1、3、5、7、9的位置添加垂直的蓝色虚线:
|
abline
(
v
=
seq
(
1
,
10
,
2
)
,
lty
=
2
,
col
=
"blue"
)
|
图例
当图形中包含的数据不止一组时,图例可用来帮助辨别出每个条形、扇形区域或折线各代表哪一类数据:
|
legend
(
location
,
title
,
legend
,
.
.
.
)
|
各参数含义如下:
- location:可直接给出图例左上角x、y坐标,或执行locator(1)之后通过鼠标单击给出图例的位置,或使用bottom、bottomleft、left、topleft、top、topright、right、bottomright以及center等关键字,如果使用了以上关键字,还可以同时使用参数inset=指定图例向图形内侧移动的大小(以绘图区域大小的分数表示);
- title:图例标题的字符串;
- legend:图例标签组成的字符型向量。
还是药物反应的例子,这下包括更多我们已经接触的内容:
1
2
3
4
5
6
7
8
9
10
11
12
|
dose
<
-
c
(
20
,
30
,
40
,
45
,
60
)
drugA
<
-
c
(
16
,
20
,
27
,
40
,
60
)
drugB
<
-
c
(
15
,
18
,
25
,
31
,
40
)
opar
<
-
par
(
no
.
readonly
=
TRUE
)
par
(
lwd
=
2
,
cex
=
1.5
,
font
.
lab
=
2
)
plot
(
dose
,
drugA
,
type
=
"b"
,
pch
=
15
,
lty
=
1
,
col
=
"red"
,
ylim
=
c
(
0
,
60
)
,
main
=
"Drug A vs. Drug B"
,
xlab
=
"Drug Dosage"
,
ylab
=
"Drug Response"
)
lines
(
dose
,
drugB
,
type
=
"b"
,
pch
=
17
,
lty
=
2
,
col
=
"blue"
)
abline
(
h
=
c
(
30
)
,
lwd
=
1.5
,
lty
=
2
,
col
=
"gray"
)
library
(
Hmisc
)
minor
.
tick
(
nx
=
3
,
ny
=
3
,
tick
.
ratio
=
0.5
)
legend
(
"topleft"
,
inset
=
.
05
,
title
=
"Drug Type"
,
c
(
"A"
,
"B"
)
,
lty
=
c
(
1
,
2
)
,
pch
=
c
(
15
,
17
)
,
col
=
c
(
"red"
,
"blue"
)
)
par
(
opar
)
|
文本标注
可以通过text()和mtext()将文添加到图形上,前者向图形内部添加,而后者将文本添加至图形的四个边界之一。