探索性数据分析

探索性数据分析是一个让我们逐步认识、理解、把握手中的待处理数据集的过程。就像淘金者若不进行地形勘测就只能盲目的四处挖掘,最后徒劳无功一样,若不进行数据探索,将无法知道对于该数据集我们应该进行何种预处理,又应使用何种挖掘算法,及相应算法参数的大致取值范围等。

一般来说,可以通过数字化统计指标,以及可视化图形两种方式相结合来展开数据的探索性分析。从中我们能够获知各变量的取值界限、是否有缺失值、分布是否有偏及偏差程度,以及各变量间的相关性等,这些信息对于选择合适的挖掘技术至关重要。比如有些技术在数据集有偏情况下,效果很差,这时就需要考虑先进行不平衡数据的预处理再使用该算法,或转而采用对有偏分布不敏感的其他算法。

a. 数据集

  #install.packages('MASS')  
  library(MASS)
  data(Insurance)                       #获取Insurance数据集
  nrow(Insurance);ncol(Insurance)       #显示Insurance数据集的行列数
  dim(Insurance)                        #显示Insurance数据集维度
  head(Insurance);tail(Insurance)       #显示前6行和后6行
  #install.packages('MASS')  
  library(MASS)
  data(Insurance)                       #获取Insurance数据集
  nrow(Insurance);ncol(Insurance)       #显示Insurance数据集的行列数
## [1] 64
## [1] 5
  dim(Insurance)                        #显示Insurance数据集维度
## [1] 64  5
  head(Insurance);tail(Insurance)       #显示前6行和后6行
##   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
##    District  Group   Age Holders Claims
## 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

b. 数据化探索

通过主要函数,得到数据集的一些数字指标值,来对数据的整体结构、变量情况、分布指标、缺失值等方面进行探索。这些数字化的探索结果或许没有图形看起来直观,但由于其给出了各项统计指标的确切取值,这对我们制作和观察图形、设定算法参数等大有裨益。

变量概况

    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
    attributes(Insurance)       #获取Insurance数据集属性列表
    str(Insurance)              #查看Insurance数据集内部结构
    summary(Insurance)          #查看Insurance数据集的变量概况
    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
## [1] "District" "Group"    "Age"      "Holders"  "Claims"
    attributes(Insurance)       #获取Insurance数据集属性列表
## $names
## [1] "District" "Group"    "Age"      "Holders"  "Claims"  
## 
## $class
## [1] "data.frame"
## 
## $row.names
##  [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
## [24] 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
## [47] 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
    str(Insurance)              #查看Insurance数据集内部结构
## 'data.frame':    64 obs. of  5 variables:
##  $ District: Factor w/ 4 levels "1","2","3","4": 1 1 1 1 1 1 1 1 1 1 ...
##  $ Group   : Ord.factor w/ 4 levels "<1l"<"1-1.5l"<..: 1 1 1 1 2 2 2 2 3 3 ...
##  $ Age     : Ord.factor w/ 4 levels "<25"<"25-29"<..: 1 2 3 4 1 2 3 4 1 2 ...
##  $ Holders : int  197 264 246 1680 284 536 696 3582 133 286 ...
##  $ Claims  : int  38 35 20 156 63 84 89 400 19 52 ...
    summary(Insurance)          #查看Insurance数据集的变量概况
##  District    Group       Age        Holders            Claims      
##  1:16     <1l   :16   <25  :16   Min.   :   3.00   Min.   :  0.00  
##  2:16     1-1.5l:16   25-29:16   1st Qu.:  46.75   1st Qu.:  9.50  
##  3:16     1.5-2l:16   30-35:16   Median : 136.00   Median : 22.00  
##  4:16     >2l   :16   >35  :16   Mean   : 364.98   Mean   : 49.23  
##                                  3rd Qu.: 327.50   3rd Qu.: 55.50  
##                                  Max.   :3582.00   Max.   :400.00

变量详情

  install.packages('Hmisc')
  library(Hmisc)
  describe(Insurance[,1:3])
  describe(Insurance[,4:5])
  install.packages('fBasics')
  library(fBasics)
  basicStats(Insurance$Holders)

分布指标

所谓“分布”,通俗来说即是指数据集中某变量各水平的取值情况。在统计学中,对于离散变量,主要有二项分布、泊松分布、几何分布等概率;而对于连续性变量,则有均匀分布、指数分布,以及最为熟知的正态分布等。每种分布都有其特殊的分布形态,我们一般倾向于用直方图、概率密度曲线等可视化方式来呈现数据的分布状况。

    library(MASS)
    data(Insurance) 
    names(Insurance)              #显示数据集的变量名称
    #install.packages('timeDate')
    library(timeDate)
    skewness(Insurance[,4:5])
    kurtosis(Insurance[,4:5])

在对数据集展开算法处理前,探究数据的分布情况是非常必要的。因为很多建立于经典假设之上的传统算法,对于数据的分布假定非常苛刻,在数据偏倚显著的情况下往往无法得到正确的估计结果。在这种情况下,就有必要通过这一数据分布的探索过程,来决定是否需要替代使用一些非参数算法,如决策树等更为现代的不依赖于分布的算法。

稀疏性

数据的稀疏性是对高维数据而言,即数据集中的变量个数成百上千,而其中的大部分变量仅对小部分样本有取值,高维数据的稀疏性在社会调查、互联网、科学实验等领域频繁出现。

    #install.packages('Matrix')
    library(Matrix)
    i=sample(1:10,10,replace=TRUE)    #在1至10中有放回地随机选取10个数,作为数据集中非空元素的行号
    j=sample(1:10,10,replace=TRUE)    #在1至10中有放回地随机选取10个数,作为数据集中非空元素的列号
    (A=sparseMatrix(i, j, x = 1))     #对第i行j列的元素取值为1,其他位置元素为空,生成稀疏矩阵A
    loca=which(A==1, arr.ind=TRUE)    #取loca变量记录各非空元素位置
    plot(loca,pch = 22)               #对如上loca变量值绘制散点图

缺失值

数据集含有缺失值是很常见的,尤其对于一些需要一个个人工收集汇总起来的数据集,很难保证每一条样本的每一个变量都有取值。比如在以问卷方式收集信息时,受访者对于有些问题不愿作答或漏答,又或者访问员记录遗漏等情况。

对于数据集中的缺失值,我们可以使用mice包中的md.pattern()函数来获取其中的缺失值分布状况。软件包mice专注于多重查补技术(Multiple Imputation),即对于缺失值等数据不足情况的处理技术。

  library(MASS)
  data(Insurance) 
  names(Insurance)            #显示数据集的变量名称  
  #install.packages('mice')
  library(mice)
  for(i in 1:10)
  { row=sample(1:64,1)        #在1至64中随机选出一个数,作为第i个缺失值所在行的序号,记为row
    col=sample(1:5,1)         #在1至5中随机选出一个数,作为第i个缺失值所在列的序号,记为col
    Insurance[row,col]=NA     #将Insurance数据集的第row行,第col列数据设为缺失值NA
  }
  md.pattern(Insurance)       #显示新数据集Insurance中的缺失值分布状况

相关性

考察变量间的相关程度是对数据集进行初步认识的过程之一。

一般来说,可以使用我们所熟知的相关系数来衡量,这是一个取值介于-1至1之间的指标。其绝对值大小表示两变量间相关性的大小,越接近1相关性越大;其符号的正负显示这两个变量间是正向(正号+)还是负向(负号-)关系。

一般来说,当相关系数取值的绝对值高于0.75我们就认为相关性较高,而对于具体问题,则需要根据其他变量间的相关性高低来判断所考察变量间的相关程度是高或低,这是一个相对而言的结论。比如,若考察10个变量间的相关程度,各变量间两两相关系数都在0.2左右,仅有一对变量相关系数取值为0.7,那么就可以认为这两个变量相对来说具有很高的相关性。

    #install.packages('rattle')
    #library(rattle)
    data(weather)
    numerics=c(12:21)
    cor_matrix=cor(weather[numerics],use="pairwise",method="pearson")
    cor_matrix
    #install.packages('ellipse')
    library(ellipse)
    plotcorr(cor_matrix,col=rep(c("white","black"),5))
    plotcorr(cor_matrix,diag=T,type="lower",col=rep(c("white","black"),5))
    data <- data.frame(longley)
    numerics=c(1:ncol(data))
    cor_matrix=cor(data[numerics],use="pairwise",method="pearson")
    cor_matrix
##              GNP.deflator       GNP Unemployed Armed.Forces Population
## GNP.deflator    1.0000000 0.9915892  0.6206334    0.4647442  0.9791634
## GNP             0.9915892 1.0000000  0.6042609    0.4464368  0.9910901
## Unemployed      0.6206334 0.6042609  1.0000000   -0.1774206  0.6865515
## Armed.Forces    0.4647442 0.4464368 -0.1774206    1.0000000  0.3644163
## Population      0.9791634 0.9910901  0.6865515    0.3644163  1.0000000
## Year            0.9911492 0.9952735  0.6682566    0.4172451  0.9939528
## Employed        0.9708985 0.9835516  0.5024981    0.4573074  0.9603906
##                   Year  Employed
## GNP.deflator 0.9911492 0.9708985
## GNP          0.9952735 0.9835516
## Unemployed   0.6682566 0.5024981
## Armed.Forces 0.4172451 0.4573074
## Population   0.9939528 0.9603906
## Year         1.0000000 0.9713295
## Employed     0.9713295 1.0000000
    library(ellipse)
    plotcorr(cor_matrix,col=rep(c("white","black"),5))

    plotcorr(cor_matrix,diag=T,type="lower",col=rep(c("white","black"),5))

观察上图,圆形的宽度表示相关性的高低,两变量所对应的圆形越窄,表明其相关性越高,比如左上至右下的对角线上的10个圆已窄成10条线段,要知道这10个位置对应的正是各变量与其自身的相关系数,取值为1,为完全相关;而圆形倾斜的方向表示相关性的正负,向右倾斜表示正相关,同样以对角线上圆形为例,右倾斜正相关。

c. 可视化探索

  按照可视化图形类别,将该部分划分为6个小节分别对直方图、累计分布图、箱型图,以及适用于离散变量的条形图、点阵图、饼图这6种图形类型予以介绍。这些图形有着各自的优势和缺陷,在实际运用过程中可以综合使用进行信息互补。

直方图

  直方图是直接了解数据分布情况最常用的图形类型,它将连续数据分为几个等间距的组,并以矩形的高低来显示相应组中所含数据的频数或和频率大小,有时可同时显示出数据的密度曲线作为辅助。这是一种简单快速的探索数据分布的方式。

    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
    # 直方图 MASS
      #对Claims变量绘制直方图
    hist(Insurance$Claims,main="Histogram of Freq of Insurance$Claims")
      #设定freq和density参数
    hist(Insurance$Claims,freq=FALSE,density=20,main="Histogram of Density of Insurance$Claims")
      #在直方图中添加概率密度曲线
    lines(density(Insurance$Claims))
      #绘制20组直方图,并标注出各组频率值
      #设置直方图中矩形颜色
    str(hist(Insurance$Claims,breaks=20,labels = TRUE,col="black",border="white",main="Histogram of Insurance$Claims with 20 bars"))

以下对Claims变量作密度直方图,其中除了freq参数外,还使用了density参数,该参数用来为各矩形添加阴影,取值越大阴影越深。breaks是绘制直方图中另一个重要参数。一般来说,hist()函数可自动对连续变量给出分组,也可以通过设定breaks值来自行分组。其中还用到labels、col、border三个参数,分别用于标注各矩形高度(频率)、更改矩形的填充和轮廓颜色。

    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
## [1] "District" "Group"    "Age"      "Holders"  "Claims"
    # 直方图 MASS
      #对Claims变量绘制直方图
    hist(Insurance$Claims,main="Histogram of Freq of Insurance$Claims")

      #设定freq和density参数
    hist(Insurance$Claims,freq=FALSE,density=20,main="Histogram of Density of Insurance$Claims")
      #在直方图中添加概率密度曲线
    lines(density(Insurance$Claims))

      #绘制20组直方图,并标注出各组频率值
      #设置直方图中矩形颜色
      #在绘图的同时,还使用了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)、绘图对象名(xname),以及是否为等距分组(equidist)。在绘制直方图时,可以将如上结果一并输出,来辅助理解图示信息。

累积分布图

累积分布图是观察数据分布情况的另一个较常用图形类型。该图形中每个点(x,y)的含义为:共有y(百分数)的数据小于或等于该x值,因此,可想而知,数据中x最大值所对应的y值为1,即100%。

直观来说,可以认为累积分布图各点斜率为上一小节中提到的概率密度曲线相应点的值,即某一点在累积分布图中的斜率越大,其概率密度越大。因此,可以将密度曲线与累积分布图相结合来考察数据分布。

    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
    # 累积分布图 Hmisc
    #install.packages('Hmisc')
    library(Hmisc)
    # 绘制Claims变量的累积分布图
    Ecdf(Insurance$Claims,xlab="Claims",main="Cumulative Distribution of Claims")
    # 形成Insurance数据集的环境
    # 构造以年龄段为<25的Claims值为变量1,“<25”为变量2的新数据集
    # 将4个新数据集按行连接为新数据集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") )
        )
    # 显示data_plot数据集内容
    data_plot
    
    
    # 首先一次绘出按Age分组的4条Claims的累积分布图,并以虚线表示。
    Ecdf(data_plot$var1,lty=2,group=data_plot$var2,label.curves=1:4,xlab="Claims", main="Cumulative Distribution of Claims by Age")
    # 再利用add参数以实线绘出Claims总体分布图
    Ecdf(Insurance$Claims,add=TRUE)
    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
## [1] "District" "Group"    "Age"      "Holders"  "Claims"
    # 累积分布图 Hmisc
    #install.packages('Hmisc')
    library(Hmisc)
## Loading required package: lattice
## Loading required package: survival
## Loading required package: Formula
## Loading required package: ggplot2
## 
## Attaching package: 'Hmisc'
## The following objects are masked from 'package:base':
## 
##     format.pval, round.POSIXt, trunc.POSIXt, units
    # 绘制Claims变量的累积分布图
    Ecdf(Insurance$Claims,xlab="Claims",main="Cumulative Distribution of Claims")

    # 形成Insurance数据集的环境
    # 构造以年龄段为<25的Claims值为变量1,“<25”为变量2的新数据集
    # 将4个新数据集按行连接为新数据集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") )
        )
    # 显示data_plot数据集内容
    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
    # 首先一次绘出按Age分组的4条Claims的累积分布图,并以虚线表示。
    Ecdf(data_plot$var1,lty=2,group=data_plot$var2,label.curves=1:4,xlab="Claims", main="Cumulative Distribution of Claims by Age")
    # 再利用add参数以实线绘出Claims总体分布图
    Ecdf(Insurance$Claims,add=TRUE)

箱形图

箱形图是能够深入展现数据分布情况的图形类型,它不仅能够给出重要分位点的位置,且会将异常点剥离出来,当进一步标注出如均值等重要指标的位置和数值后,数据的整体结构就能够被清晰地勾勒在的图形中。

    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
    # 箱型图
        # 对Claims变量绘制箱形图,图形名称为“Distribution of Claims”
    Claims_bp=boxplot(Insurance$Claims,main="Distribution of Claims")
        # 获取箱形图的5个界限值
    Claims_bp$stats
        # 用星号标记出均值的位置
    points(x=1,y=mean(Insurance$Claims),pch=8)
        # 获取超出上侧延展线的6个异常值的取值
    Claims_points=as.matrix(Insurance$Claims[which(Insurance$Claims>102)],6,1)
        # 将待标注12个点的取值汇总于Claims_text,包括箱形图的5个主要点、均值、6个异常值
    Claims_text=rbind(Claims_bp$stats,mean(Insurance$Claims),Claims_points)
        # 将12个点的取值标注于箱形图的相应位置
    for(i in 1:length(Claims_text)) text(x=1.1,y=Claims_text[i,],labels=Claims_text[i,])
        # 以data_plot数据集中的var1对var2绘图,且横向输出图形,并设置图形的名称,以及横纵轴变量名
    boxplot(var1~var2,data=data_plot,horizontal=TRUE,main="Distribution of Claims by Age",xlab="Claims",ylab="Age")
    
    # 形成Insurance数据集的环境
    with(Insurance, 
      {
        # 绘制第一个箱子:>35年龄段下的Holders分布
        boxplot(Holders ~ Age, boxwex=0.25, at=1:4+0.2,subset = Age == ">35")
        # 绘制第二个箱子:30-35年龄段下的Holders分布
        boxplot(Holders ~ Age, add = TRUE, boxwex=0.25, at=1:4+0.2,subset = Age == "30-35")
        # 绘制第三个箱子:25-29年龄段下的Holders分布
        boxplot(Holders ~ Age, add = TRUE, boxwex=0.25, at=1:4+0.2,subset = Age == "25-29")
        # 绘制第四个箱子:<25年龄段下的Holders分布
        boxplot(Holders ~ Age, add = TRUE, boxwex=0.25, at=1:4+0.2,subset = Age == "<25") 
      } )
    # 加入Age划分的Claims变量箱形图,即加入另外四个箱子:各年龄段下的Claims分布
    # 将Claims的四个箱子填充为浅灰色,并设定图形及坐标轴名称
    boxplot(var1~var2, data=data_plot, add = TRUE, boxwex=0.25, at=1:4 - 0.2, 
            col="lightgrey", main="Distribution of Claims&Holders by Age",
            xlab="Age", ylab="Claims&Holders")
    # 为"Claims"和"Holders"各自的四个箱子加上图例
    legend(x="topleft", c("Claims", "Holders"), fill = c("lightgrey", "white"))
    # 以list形式生成用于绘图的数据集data_bp
    data_bp=list(data_plot$var1[which(data_plot$var2=="<25")],
                 data_plot$var1[which(data_plot$var2=="25-29")],
                 data_plot$var1[which(data_plot$var2=="30-35")],
                 data_plot$var1[which(data_plot$var2==">35")])
    # 显示数据集data_bp的4部分内容
    data_bp
    # 绘制以Age划分的Claims变量比例的箱形图
    bpplot(data_bp,name=c("<25","25-29","30-35",">35"),xlab="Age", ylab="Claims")
    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
## [1] "District" "Group"    "Age"      "Holders"  "Claims"
    # 箱型图
        # 对Claims变量绘制箱形图,图形名称为“Distribution of Claims”
    Claims_bp=boxplot(Insurance$Claims,main="Distribution of Claims")
        # 获取箱形图的5个界限值
    Claims_bp$stats
##      [,1]
## [1,]    0
## [2,]    9
## [3,]   22
## [4,]   58
## [5,]  102
## attr(,"class")
##           
## "integer"
        # 用星号标记出均值的位置
    points(x=1,y=mean(Insurance$Claims),pch=8)
        # 获取超出上侧延展线的6个异常值的取值
    Claims_points=as.matrix(Insurance$Claims[which(Insurance$Claims>102)],6,1)
        # 将待标注12个点的取值汇总于Claims_text,包括箱形图的5个主要点、均值、6个异常值
    Claims_text=rbind(Claims_bp$stats,mean(Insurance$Claims),Claims_points)
        # 将12个点的取值标注于箱形图的相应位置
    for(i in 1:length(Claims_text)) text(x=1.1,y=Claims_text[i,],labels=Claims_text[i,])

        # 以data_plot数据集中的var1对var2绘图,且横向输出图形,并设置图形的名称,以及横纵轴变量名
    boxplot(var1~var2,data=data_plot,horizontal=TRUE,main="Distribution of Claims by Age",xlab="Claims",ylab="Age")

    # 形成Insurance数据集的环境
    with(Insurance, 
      {
        # 绘制第一个箱子:>35年龄段下的Holders分布
        boxplot(Holders ~ Age, boxwex=0.25, at=1:4+0.2,subset = Age == ">35")
        # 绘制第二个箱子:30-35年龄段下的Holders分布
        boxplot(Holders ~ Age, add = TRUE, boxwex=0.25, at=1:4+0.2,subset = Age == "30-35")
        # 绘制第三个箱子:25-29年龄段下的Holders分布
        boxplot(Holders ~ Age, add = TRUE, boxwex=0.25, at=1:4+0.2,subset = Age == "25-29")
        # 绘制第四个箱子:<25年龄段下的Holders分布
        boxplot(Holders ~ Age, add = TRUE, boxwex=0.25, at=1:4+0.2,subset = Age == "<25") 
      } )
    # 加入Age划分的Claims变量箱形图,即加入另外四个箱子:各年龄段下的Claims分布
    # 将Claims的四个箱子填充为浅灰色,并设定图形及坐标轴名称
    boxplot(var1~var2, data=data_plot, add = TRUE, boxwex=0.25, at=1:4 - 0.2, 
            col="lightgrey", main="Distribution of Claims&Holders by Age",
            xlab="Age", ylab="Claims&Holders")
    # 为"Claims"和"Holders"各自的四个箱子加上图例
    legend(x="topleft", c("Claims", "Holders"), fill = c("lightgrey", "white"))

    # 以list形式生成用于绘图的数据集data_bp
    data_bp=list(data_plot$var1[which(data_plot$var2=="<25")],
                 data_plot$var1[which(data_plot$var2=="25-29")],
                 data_plot$var1[which(data_plot$var2=="30-35")],
                 data_plot$var1[which(data_plot$var2==">35")])
    # 显示数据集data_bp的4部分内容
    data_bp
## [[1]]
##  [1] 38 63 19  4 22 25 14  4  5 10  8  3  2  7  5  0
## 
## [[2]]
##  [1] 35 84 52 18 19 51 46 15 11 24 19  2  5 10  7  6
## 
## [[3]]
##  [1] 20 89 74 19 22 49 39 12 10 37 24  8  4 22 16  8
## 
## [[4]]
##  [1] 156 400 233  77  87 290 143  53  67 187 101  37  36 102  63  33
    # 绘制以Age划分的Claims变量比例的箱形图
    bpplot(data_bp,name=c("<25","25-29","30-35",">35"),xlab="Age", ylab="Claims")

条形图

条形图与柱状图类似,不同之处在于,柱状图适用于连续型数据,通过人为分组而形成若干矩形来构成图形;而条形图则是用于离散型变量,该变量的每一个水平自然成为一个条形来显示该水平的取值情况。因此,条形图是与柱状图的构成方式是相似的,用于显示离散型变量分布情况的图形类型。

    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
    # 条形图
    # sum(Claims[which(Age=="<25")])  #计算<25年龄组的Claims之和
    # 分别计算各年龄组的Claims之和后,以c()函数生成向量Claims_Age
    Claims_Age = with(Insurance,
                    c( sum(Claims[which(Age=="<25")]), sum(Claims[which(Age=="25-29")]),
                       sum(Claims[which(Age=="30-35")]), sum(Claims[which(Age==">35")]) ) )
    # 查看Claims_Age的值
    Claims_Age
    # 绘制条形图,并设置四个矩阵的名称依次为"<25","25-29","30-35",">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")
    # 分别计算各年龄组的Holders之和后,以c()函数生成向量Holders_Age
    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的值
    Holders_Age
    # 将Claims_Age和Holders_Age合并成为data_bar
    data_bar = rbind(Claims_Age,Holders_Age)
    # 查看data_bar的值
    data_bar
    # 绘图、加标签  将beside设置为TRUE,绘制出分组条形图
    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"))
    # 绘图、加标签  将beside设置为FALSE,绘制出堆叠条形图
    barplot(data_bar, names.arg=c("<25","25-29","30-35",">35"),
            main="Age Distribution by Claims and Holders",
           ylab="Claims&Holders", col=c("black","darkgrey"))
    legend(x="topleft", rownames(data_bar), fill = c("black","darkgrey"))
    library(MASS)
    data(Insurance) 
    names(Insurance)            #显示数据集的变量名称
## [1] "District" "Group"    "Age"      "Holders"  "Claims"
    # 条形图
    # sum(Claims[which(Age=="<25")])  #计算<25年龄组的Claims之和
    # 分别计算各年龄组的Claims之和后,以c()函数生成向量Claims_Age
    Claims_Age = with(Insurance,
                    c( sum(Claims[which(Age=="<25")]), sum(Claims[which(Age=="25-29")]),
                       sum(Claims[which(Age=="30-35")]), sum(Claims[which(Age==">35")]) ) )
    # 查看Claims_Age的值
    Claims_Age
## [1]  229  404  453 2065
    # 绘制条形图,并设置四个矩阵的名称依次为"<25","25-29","30-35",">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")

    # 分别计算各年龄组的Holders之和后,以c()函数生成向量Holders_Age
    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的值
    Holders_Age
## [1]  1138  2336  3007 16878
    # 将Claims_Age和Holders_Age合并成为data_bar
    data_bar = rbind(Claims_Age,Holders_Age)
    # 查看data_bar的值
    data_bar
##             [,1] [,2] [,3]  [,4]
## Claims_Age   229  404  453  2065
## Holders_Age 1138 2336 3007 16878
    # 绘图、加标签  将beside设置为TRUE,绘制出分组条形图
    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"))

    # 绘图、加标签  将beside设置为FALSE,绘制出堆叠条形图
    barplot(data_bar, names.arg=c("<25","25-29","30-35",">35"),
            main="Age Distribution by Claims and Holders",
           ylab="Claims&Holders", col=c("black","darkgrey"))
    legend(x="topleft", rownames(data_bar), fill = c("black","darkgrey"))

点阵图

点阵图与条形图本质上是一样的,也是用于呈现离散型变量各取值水平的分布情况,不同之处在于用点和背景网格线的形式代替条形来表示。

    # 点阵图
    # 绘制点阵图
    dotchart(data_bar,xlab="Claims&Holders", pch=1:2,
             main="Age Distribution by Claims and Holders")
    # 为第一年龄组添加图例
    legend(x=14000,y=15,"<25",bty="n")
    # 为第二年龄组添加图例
    legend(x=14000,y=11,"25-29",bty="n")
    # 为第三年龄组添加图例
    legend(x=14000,y=7,"30-35",bty="n")
    # 为第四年龄组添加图例
    legend(x=14000,y=3,">35",bty="n") 
    # 点阵图
    # 绘制点阵图
    dotchart(data_bar,xlab="Claims&Holders", pch=1:2,
             main="Age Distribution by Claims and Holders")
    # 为第一年龄组添加图例
    legend(x=14000,y=15,"<25",bty="n")
    # 为第二年龄组添加图例
    legend(x=14000,y=11,"25-29",bty="n")
    # 为第三年龄组添加图例
    legend(x=14000,y=7,"30-35",bty="n")
    # 为第四年龄组添加图例
    legend(x=14000,y=3,">35",bty="n") 

饼图

饼图是考察单个变量分布情况的有效图形,其绘制和解读过程都十分简单。

    # 饼图
    # 绘制Age变量Claims取值的饼图
    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)
    # 设置图形各部分图例的文本内容
    label = paste(paste(c("<25","25-29","30-35",">35"),":"), percent,"%",sep="")
    # Age变量Claims取值的百分比饼图
    pie(Claims_Age,labels = label,  
        main="Pie Chart of Age by Claims",col=c("white","lightgray","darkgrey","black"))
    
    #install.packages('plotrix')
    library(plotrix)
    pie3D(Claims_Age,labels=c("<25","25-29","30-35",">35"),explode=0.05,
          main="3D Pie Chart of Age by Claims",labelcex=0.8,
          col=c("white","lightgray","darkgrey","black"))
    # 饼图
    # 绘制Age变量Claims取值的饼图
    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)
    # 设置图形各部分图例的文本内容
    label = paste(paste(c("<25","25-29","30-35",">35"),":"), percent,"%",sep="")
    # Age变量Claims取值的百分比饼图
    pie(Claims_Age,labels = label,  
        main="Pie Chart of Age by Claims",col=c("white","lightgray","darkgrey","black"))

    #install.packages('plotrix')
    library(plotrix)
    pie3D(Claims_Age,labels=c("<25","25-29","30-35",">35"),explode=0.05,
          main="3D Pie Chart of Age by Claims",labelcex=0.8,
          col=c("white","lightgray","darkgrey","black"))