加载Insurance数据集(该数据集在MASS包中)
library(MASS)
data(mtcars)
展示数据集
Insurance
## District Group Age Holders Claims
## 1 1 <1l <25 197 38
## 2 1 <1l 25-29 264 35
## 3 1 <1l 30-35 246 20
## 4 1 <1l >35 1680 156
## 5 1 1-1.5l <25 284 63
## 6 1 1-1.5l 25-29 536 84
## 7 1 1-1.5l 30-35 696 89
## 8 1 1-1.5l >35 3582 400
## 9 1 1.5-2l <25 133 19
## 10 1 1.5-2l 25-29 286 52
## 11 1 1.5-2l 30-35 355 74
## 12 1 1.5-2l >35 1640 233
## 13 1 >2l <25 24 4
## 14 1 >2l 25-29 71 18
## 15 1 >2l 30-35 99 19
## 16 1 >2l >35 452 77
## 17 2 <1l <25 85 22
## 18 2 <1l 25-29 139 19
## 19 2 <1l 30-35 151 22
## 20 2 <1l >35 931 87
## 21 2 1-1.5l <25 149 25
## 22 2 1-1.5l 25-29 313 51
## 23 2 1-1.5l 30-35 419 49
## 24 2 1-1.5l >35 2443 290
## 25 2 1.5-2l <25 66 14
## 26 2 1.5-2l 25-29 175 46
## 27 2 1.5-2l 30-35 221 39
## 28 2 1.5-2l >35 1110 143
## 29 2 >2l <25 9 4
## 30 2 >2l 25-29 48 15
## 31 2 >2l 30-35 72 12
## 32 2 >2l >35 322 53
## 33 3 <1l <25 35 5
## 34 3 <1l 25-29 73 11
## 35 3 <1l 30-35 89 10
## 36 3 <1l >35 648 67
## 37 3 1-1.5l <25 53 10
## 38 3 1-1.5l 25-29 155 24
## 39 3 1-1.5l 30-35 240 37
## 40 3 1-1.5l >35 1635 187
## 41 3 1.5-2l <25 24 8
## 42 3 1.5-2l 25-29 78 19
## 43 3 1.5-2l 30-35 121 24
## 44 3 1.5-2l >35 692 101
## 45 3 >2l <25 7 3
## 46 3 >2l 25-29 29 2
## 47 3 >2l 30-35 43 8
## 48 3 >2l >35 245 37
## 49 4 <1l <25 20 2
## 50 4 <1l 25-29 33 5
## 51 4 <1l 30-35 40 4
## 52 4 <1l >35 316 36
## 53 4 1-1.5l <25 31 7
## 54 4 1-1.5l 25-29 81 10
## 55 4 1-1.5l 30-35 122 22
## 56 4 1-1.5l >35 724 102
## 57 4 1.5-2l <25 18 5
## 58 4 1.5-2l 25-29 39 7
## 59 4 1.5-2l 30-35 68 16
## 60 4 1.5-2l >35 344 63
## 61 4 >2l <25 3 0
## 62 4 >2l 25-29 16 6
## 63 4 >2l 30-35 25 8
## 64 4 >2l >35 114 33
其中,District(离散型)投保人所在街区;group(离散型)投保人汽车排量;Age(离散型)投保人年龄;Holders(连续型)投保人数量;Claims(连续型)索赔人数量;
画散点图:横轴x=Holders,纵轴y=Claims。
attach(Insurance)
plot(Holders,Claims)
detach(Insurance)
函数attach()将数据加载入内存中,detach()将数据从内存中删除。
我们还可以使用with()函数,来创建该数据的环境。
with(Insurance,
plot(Holders,Claims)
)
思考:如果不用attach(),with()函数可以加载数据,绘制散点图吗?
在之前散点图的基础上,添加一条拟合曲线。
with(Insurance,{
plot(Holders,Claims)
abline(lm(Claims ~ Holders))}
)
注意:在with函数中,有多个函数时,必须使用{}。函数abline()表示添加一条直线。lm(y ~ x)表示拟合的一条直线。
在之前绘图的基础上,添加标题
attach(Insurance)
plot(Holders,Claims)
abline(lm(Claims ~ Holders))
title("Regression of Claims on Holders")
注意:因为后面还要用到Insurance数据集,所以就不使用detach()函数了。
在之前基础上,将图形保存到当前工作目录中名为mygraph.pdf的PDF文件中。
pdf("mygraph.pdf")
plot(Holders,Claims)
abline(lm(Claims ~ Holders))
title("Regression of Claims on Holders")
注意:除了pdf(),还可以使用函数win.metafile()、png()、jpeg()、bmp()、tiff()、xfig()和postscript()将图形保存为其他格式。
保存为jpeg格式
jpeg("mygraph.jpeg")
plot(Holders,Claims)
abline(lm(Claims ~ Holders))
title("Regression of Claims on Holders")
下表描述了病人对两种药物五个剂量水平上的响应情况。
使用以下代码输入数据:
dose <- c(20, 30, 40, 45, 60)
drugA <- c(16, 20, 27, 40, 60)
drugB <- c(15, 18, 25, 31, 40)
dose剂量,drugA药物A的响应时间,drugB药物B的响应时间
创建一幅描述药物A的剂量dose和响应时间drugA关系的图形
plot(dose, drugA, type = "b")
注意:plot(x, y, type=“b”) 表示将x置于横轴,将y置于纵轴,绘制点集(x,y)。选项type=“b”表示将点连成线。
我们可以通过修改图形参数来自定义一幅图形的多个特征(字体、颜色、坐标轴、标题)。修改图形参数的一种方法是通过函数par()来指定这些选项。
假设你想修改上图,使用实心三角而不是空心圆圈作为点的符号,并且想用虚线代替实线连接这些点。
可以使用以下代码完成修改:
plot(dose, drugA, type = "b", lty = 2, pch = 17)
可以使用图形参数来指定绘图时使用的符号和线条类型。相关参数如下表所示。
选项pch=用于指定绘制点时使用的符号。pch取值如下图所示。
选项lty=用于指定想要的线条类型。lty取值如下图所示。
绘制一幅图形,其线条类型为点线,宽度为默认宽度的3倍,点的符号为实心正方形,大小为默认符号大小的2倍。可以通过代码设置:
plot(dose, drugA, type = "b", lty = 3, lwd = 3, pch = 15, cex = 2)
该部分主要进行数据分析的可视化探索。
针对-连续型数据-介绍:直方图、累积分布图、箱形图。
针对-离散型数据-介绍:条形图、点阵图、饼图。
直方图将连续型数据分为几个等间距的组,并以矩形的高低来显示相应组中所含数据的频数或频率大小。
绘制Isurance数据集中Claims变量的直方图
hist(Claims,main="Histogram of Freq of Insurance$Claims")
hist()函数中,参数freg=TRUE(默认)表示频数绘制;freq=FALSE表示根据概率密度绘制图形。
hist(Claims,freq=FALSE,main="Histogram of Density of Insurance$Claims")
注意:此时矩阵高度代表各组的概率密度,同时各组矩阵面积之和为1。
参数density可为各组矩阵添加阴影,取值越大,阴影部分越深。
当density=10时
hist(Claims,freq=FALSE,density=10,main="Histogram of Density of Insurance$Claims")
当density=20时
hist(Claims,freq=FALSE,density=20,main="Histogram of Density of Insurance$Claims")
在之前直方图基础上,同时绘制概率密度曲线
hist(Claims,freq=FALSE,density=20,main="Histogram of Density of Insurance$Claims")
lines(density(Insurance$Claims))
注意:通过密度曲线,可以精确看到每一取值所对应的概率密度值,同时密度曲线与x轴围成的面积为1。
参数breaks用于控制组的数量。当breaks=20时
hist(Insurance$Claims,breaks=20, main="Histogram of Insurance$Claims with 20 bars")
参数labels = TRUE可显示每组频数。参数col可更换矩形内颜色。参数border可更换边框颜色。
hist(Insurance$Claims,breaks=20,labels = TRUE, col="blue",border="red", main="Histogram of Insurance$Claims with 20 bars" )
在绘图的同时,还可使用str()函数获取该直方图的相应输出值。
str(hist(Insurance$Claims,breaks=20,labels = TRUE, col="black",border="white",main="Histogram of Insurance$Claims with 20 bars"))
## List of 6
## $ breaks : num [1:21] 0 20 40 60 80 100 120 140 160 180 ...
## $ counts : int [1:20] 30 13 5 5 3 2 0 2 0 1 ...
## $ density : num [1:20] 0.02344 0.01016 0.00391 0.00391 0.00234 ...
## $ mids : num [1:20] 10 30 50 70 90 110 130 150 170 190 ...
## $ xname : chr "Insurance$Claims"
## $ equidist: logi TRUE
## - attr(*, "class")= chr "histogram"
注意:以上6项输出结果,分别列示出各组边界值(breaks)、频数(counts)、概率密度(density), 中间值(mids)、绘图对象名(Name),以及是否为等距分组(equidist)。在绘制直方图时,可以将如上结果一并输出,来辅助理解图示信息。
累积分布图中每个点(x,y)的含义为:共有y(百分数)的数据小于或等于该x值。数据中x最大值所对应的y值为1。
使用Himsc软件包中的Ecd()函数来绘制累积分布图, 首次使用需要首先下载此包。
library(lattice)
library(survival)
library(Formula)
library(ggplot2)
library(Hmisc)
##
## Attaching package: 'Hmisc'
## The following objects are masked from 'package:base':
##
## format.pval, units
以Claims变量为例,用Ecdf()函数来绘制累积分布图
Ecdf(Insurance$Claims,xlab="Claims",main="Cumulative Distribution of Claims")
在一张图中,绘制各个年龄段Age的索赔人数claims的累积分布图。
观察一下这两个变量
Insurance[,c("Age","Claims")]
## Age Claims
## 1 <25 38
## 2 25-29 35
## 3 30-35 20
## 4 >35 156
## 5 <25 63
## 6 25-29 84
## 7 30-35 89
## 8 >35 400
## 9 <25 19
## 10 25-29 52
## 11 30-35 74
## 12 >35 233
## 13 <25 4
## 14 25-29 18
## 15 30-35 19
## 16 >35 77
## 17 <25 22
## 18 25-29 19
## 19 30-35 22
## 20 >35 87
## 21 <25 25
## 22 25-29 51
## 23 30-35 49
## 24 >35 290
## 25 <25 14
## 26 25-29 46
## 27 30-35 39
## 28 >35 143
## 29 <25 4
## 30 25-29 15
## 31 30-35 12
## 32 >35 53
## 33 <25 5
## 34 25-29 11
## 35 30-35 10
## 36 >35 67
## 37 <25 10
## 38 25-29 24
## 39 30-35 37
## 40 >35 187
## 41 <25 8
## 42 25-29 19
## 43 30-35 24
## 44 >35 101
## 45 <25 3
## 46 25-29 2
## 47 30-35 8
## 48 >35 37
## 49 <25 2
## 50 25-29 5
## 51 30-35 4
## 52 >35 36
## 53 <25 7
## 54 25-29 10
## 55 30-35 22
## 56 >35 102
## 57 <25 5
## 58 25-29 7
## 59 30-35 16
## 60 >35 63
## 61 <25 0
## 62 25-29 6
## 63 30-35 8
## 64 >35 33
先按照书上的程序实现,创建一个数据集data_plot
data_plot=with(Insurance,
rbind(data.frame(var1=Claims[Age=="<25"],var2="<25"),
data.frame(var1=Claims[Age=="25-29"],var2="25-29"),
data.frame(var1=Claims[Age=="30-35"],var2="30-35"),
data.frame(var1=Claims[Age==">35"],var2=">35") )
)
函数with()用于形成Insurance数据集的环境,这样在使用该数据集中的各变量时,就不需在每次都采用Insurance$Claims方式指定数据集,只用输入Claims,简化了代码编写。
函数data.frame()则用于构造新的数据集。
函数rbind()函数可将各部分数据按行连接起来。
data_plot
## var1 var2
## 1 38 <25
## 2 63 <25
## 3 19 <25
## 4 4 <25
## 5 22 <25
## 6 25 <25
## 7 14 <25
## 8 4 <25
## 9 5 <25
## 10 10 <25
## 11 8 <25
## 12 3 <25
## 13 2 <25
## 14 7 <25
## 15 5 <25
## 16 0 <25
## 17 35 25-29
## 18 84 25-29
## 19 52 25-29
## 20 18 25-29
## 21 19 25-29
## 22 51 25-29
## 23 46 25-29
## 24 15 25-29
## 25 11 25-29
## 26 24 25-29
## 27 19 25-29
## 28 2 25-29
## 29 5 25-29
## 30 10 25-29
## 31 7 25-29
## 32 6 25-29
## 33 20 30-35
## 34 89 30-35
## 35 74 30-35
## 36 19 30-35
## 37 22 30-35
## 38 49 30-35
## 39 39 30-35
## 40 12 30-35
## 41 10 30-35
## 42 37 30-35
## 43 24 30-35
## 44 8 30-35
## 45 4 30-35
## 46 22 30-35
## 47 16 30-35
## 48 8 30-35
## 49 156 >35
## 50 400 >35
## 51 233 >35
## 52 77 >35
## 53 87 >35
## 54 290 >35
## 55 143 >35
## 56 53 >35
## 57 67 >35
## 58 187 >35
## 59 101 >35
## 60 37 >35
## 61 36 >35
## 62 102 >35
## 63 63 >35
## 64 33 >35
用Ecdf()函数绘制按Age分组的累积分布图
Ecdf(data_plot$var1,lty=2,group=data_plot$var2,label.curves=TRUE,
xlab="Claims", main="Cumulative Distribution of Claims by Age")
其中用到lty、group、label.curves这3个参数。lty用于设定线条的类型。group用于设置分组变量,例如这里我们将Age作为分组变量;
label. curves=TRUE(默认)用于标出按分组变量划分的各曲线组名。
书上的程序,经过精简,可修改为
Ecdf(Insurance$Claims,lty=2,group=Insurance$Age,label.curves=TRUE,
xlab="Claims", main="Cumulative Distribution of Claims by Age")
在之前图形的基础上,加入1条实线绘制的Claims的总体累积分布图。
Ecdf(data_plot$var1,lty=2,group=data_plot$var2,label.curves=1:4,
xlab="Claims", main="Cumulative Distribution of Claims by Age")
Ecdf(Insurance$Claims,add=TRUE)
其中要用到add参数,add参数表示是否在上一输出图形中添加图像。
箱线图(又称盒须图)通过绘制连续型变量的五个特征数,即最小值、下四分位数(第25百分位数)、中位数(第50百分位数)、上四分位数(第75百分位数)以及最大值,描述了连续型变量的分布。
在默认情况下,两条须的延伸极限不会超过盒型各端加1.5倍四分位距的范围。此范围以外的值将以点来表示。箱线图能够显示出可能为离群点(范围±1.5*IQR以外的值, IQR表示四分位距,即上 四分位数与下四分位数的差值)的观测。
使用boxplot()函数,绘制数据集中Claims的线形图
Claims_bp=boxplot(Insurance$Claims,main="Distribution of Claims")
观察箱型图中的各种详细信息
Claims_bp
## $stats
## [,1]
## [1,] 0
## [2,] 9
## [3,] 22
## [4,] 58
## [5,] 102
## attr(,"class")
##
## "integer"
##
## $n
## [1] 64
##
## $conf
## [,1]
## [1,] 12.3225
## [2,] 31.6775
##
## $out
## [1] 156 400 233 290 143 187
##
## $group
## [1] 1 1 1 1 1 1
##
## $names
## [1] ""
其中Claims_bp$stats表示claims变量的各分位点情况
Claims_bp$stats
## [,1]
## [1,] 0
## [2,] 9
## [3,] 22
## [4,] 58
## [5,] 102
## attr(,"class")
##
## "integer"
其中,第1个数值0代表下须位。中间的三个值,即第2、3、4对应的数值9、22、58分别表示该变量的下四分位数、中位数、上四分位数,这三个点确定了箱型图中“箱子”的大小,而箱子中的黑线位置即为中位数,且上四分位数与下四分位数之差58-9=49,被称为四分位距IQR;超出上须线和下须线的点作为异常值被单独标出。58+1.5*49=131.5。我们查看一下claims变量的数据发现,低于131.5的数据是102,高于131.5的数据是143。
我们从上图可以看到该数据显现右偏趋势,同时将6个极大异常值点被标注。
在之前的基础上,用星号标记出均值的位置
Claims_bp=boxplot(Claims,main="Distribution of Claims")
points(x=1,y=mean(Claims),pch=8)
函数mean()表示求平均值
在之前的基础上,标记出各重要点的具体取值来进一步完善箱线图。
将离群点以矩阵方式保存:
Claims_points=as.matrix(Claims[which(Insurance$Claims>102)],6,1)
6表示6行,1表示1列。
将需要标注的12点给汇聚在Claims_text新数据集中
Claims_text=rbind(Claims_bp$stats,mean(Claims),Claims_points)
Claims_bp=boxplot(Insurance$Claims,main="Distribution of Claims")
points(x=1,y=mean(Insurance$Claims),pch=8)
for(i in 1:length(Claims_text))
text(x=1.3,y=Claims_text[i,],labels=Claims_text[i,])
当要绘制多个箱型图时,我们需要输出横向的箱线图。
( 我们先来看默认的纵向的箱线图。
data_plot=with(Insurance,
rbind(data.frame(var1=Claims[Age=="<25"],var2="<25"),
data.frame(var1=Claims[Age=="25-29"],var2="25-29"),
data.frame(var1=Claims[Age=="30-35"],var2="30-35"),
data.frame(var1=Claims[Age==">35"],var2=">35") )
)
boxplot(var1~var2,data=data_plot,
main="Distribution of Claims by Age",xlab="Age",ylab="Claims")
在之前的基础上,我们输出横向的箱线图。
boxplot(var1~var2,data=data_plot,horizontal=TRUE,
main="Distribution of Claims by Age",xlab="Claims",ylab="Age")
其中参数horizontal=TRUE时,表示输出横向箱线图。
条形图与柱状图类似。柱状图适用于连续型数据,条形图适用于离散型变量。
下面我们研究Isurance数据集中离散变量Age的分布情况,并以Claims作为各年龄组的取值频率。(x轴为Age,y轴为Claims)
Claims_Age = with(Insurance,
c( sum(Claims[Age=="<25"]), sum(Claims[Age=="25-29"]),
sum(Claims[Age=="30-35"]), sum(Claims[Age==">35"]) ) )
attach(Insurance)
## The following objects are masked from Insurance (pos = 8):
##
## Age, Claims, District, Group, Holders
Claims_Age1 = c( sum(Claims[which(Age=="<25")]), sum(Claims[which(Age=="25-29")]),
sum(Claims[which(Age=="30-35")]), sum(Claims[which(Age==">35")])
)
barplot(Claims_Age,names.arg=c("<25","25-29","30-35",">35"),density=rep(20,4),
main="Distribution of Age by Claims", xlab="Age", ylab="Claims")
barplot()函数中的参数names.arg表示标注x轴每个组别的名称,density表示条形图框内阴影斜线的密度,main表示图形名称。
小练习:研究Isurance数据集中离散变量Group的分布情况,并以Holders作为各年龄组的取值频率。
进一步,我们将Holders变量加入考虑,使得各年龄Age组下的Claims和Holders值同时存在于一张图中,便于比较分析。
常用的合并条形图主要有:分组条形图,堆叠条形图。分组条形图是将同一Age组别下的的Claims和Holders值并行摆放在一起,堆叠条形图是将其堆叠在一个矩形中表示。
绘制分组条形图。首先先得到向量Holders_Age来储存四个年龄组下的Holders值,并将Claims_Age和Holders_Age合并为data_bar矩阵用于绘图。
Holders_Age = with(Insurance,
c( sum(Holders[which(Age=="<25")]), sum(Holders[which(Age=="25-29")]),
sum(Holders[which(Age=="30-35")]), sum(Holders[which(Age==">35")]) ) )
Holders_Age
## [1] 1138 2336 3007 16878
将Claims_Age和Holders_Age合并为data_bar矩阵。
data_bar = rbind(Claims_Age,Holders_Age)
data_bar
## [,1] [,2] [,3] [,4]
## Claims_Age 229 404 453 2065
## Holders_Age 1138 2336 3007 16878
绘制分组条形图
barplot(data_bar, names.arg=c("<25","25-29","30-35",">35"),beside=TRUE,
main="Age Distribution by Claims and Holders",
xlab="Age", ylab="Claims&Holders", col=c("black","darkgrey"))
其中参数beside=TRUE时,表示为分组条形图。beside=FALSE时(默认),表示为堆叠条形图。
barplot(data_bar, names.arg=c("<25","25-29","30-35",">35"),beside=TRUE,
main="Age Distribution by Claims and Holders",
xlab="Age", ylab="Claims&Holders", col=c("black","darkgrey"))
legend(x="topleft",rownames(data_bar), fill = c("black","darkgrey"))
函数legend()表示给两个并列的组进行注释说明。参数x表示注释的位置,有时用x=,y=表示注释的位置。
绘制堆叠条形图
barplot(data_bar, names.arg=c("<25","25-29","30-35",">35"),beside=FALSE,
main="Age Distribution by Claims and Holders",
ylab="Claims&Holders", col=c("black","darkgrey"))
legend(x="topleft", rownames(data_bar), fill = c("black","darkgrey"))
小练习:分组条形图和堆叠条形图中每组的数值如何显示?
点阵图的本质和条形图是一致的,也是用于呈现离散型变量各取值水平的分布情况。
我们使用在不同Age年龄组下的Claims和Holders值的矩阵data_bar来生成点阵图。
dotchart(data_bar,xlab="Claims&Holders", pch=1:2,
main="Age Distribution by Claims and Holders")
legend(x=14000,y=16,"<25",bty="n")
legend(x=14000,y=12,"25-29",bty="n")
legend(x=14000,y=8,"30-35",bty="n")
legend(x=14000,y=4,">35",bty="n")
参数bty表示图例框是否画出,o为画出(默认),n不画出。
饼图是观察某个离散变量分布情况的有效图形。
以离散变量Age为例,绘制其Claims的取值情况。使用pie()函数绘制。
pie(Claims_Age,labels=c("<25","25-29","30-35",">35"),
main="Pie Chart of Age by Claims",col=c("white","lightgray","darkgrey","black"))
有时需要展示各部分所占的比例值。那就需要先计算各部分的百分比,然后在绘图。我们以上面的为例展示。
计算各组的比例
percent = round(Claims_Age/sum(Claims_Age)*100)
percent
## [1] 7 13 14 66
round()函数表示四舍五入,sum()表示求和。
设置饼图各部分文本信息
label = paste(paste(c("<25","25-29","30-35",">35"),":"), percent,"%",sep="")
paste()函数表示连接函数,参数sep表示连接之间的间隔。
绘制带百分比信息的饼图
pie(Claims_Age,labels = label,
main="Pie Chart of Age by Claims",col=c("white","lightgray","darkgrey","black"))