美文网首页R语言与统计R语言知识干货
R语言系列第三期:②R语言多组汇总及图形展示

R语言系列第三期:②R语言多组汇总及图形展示

作者: 765f2ea50d22 | 来源:发表于2019-04-09 18:08 被阅读25次

    本文首发于 ”百味科研芝士“ 微信公众号,转载请注明:百味科研芝士,Focus科研人的百味需求

    上一部分里我们给大家介绍了单组数据或者不分组数据的统计描述的方法,详情点击:

    A. 事实上,我们在实验中或者调查之后的分析往往希望通过分组比较来获得有统计学意义的结果,因此分组数据在我们平常的工作中更加常见,也更加科学严谨,那么我们就来了解下分组数据的描述。

    ① 当处理分组数据的时候,你会希望得到一些按组别分类计算的不同统计量,比如均值和标准差等形成的一张表格。这里可以使用tapply()函数。

    在这里我们就得介绍一下R的隐式循环了,之前我们学习过while循环,repeat,break循环,for循环;循环的一个常用功能是把一个函数应用到一组值或者向量中的每一个元素,并将结果返回。在R中,就可以使用lapply()和sapply()两个函数实现。前一个总是返回列表(用“l”标识),而后者则尽可能将结果简化(用“s”标识)成向量或矩阵。因此,计算数值向量组成的数据框中每个变量的均值可以如下操作:

    > lapply(thuesen,mean,na.rm=T)

    $blood.glucose

    [1] 10.3

    $short.velocity

    [1] 1.325652

    > sapply(thuesen,mean,na.rm=T)

    blood.glucose   short.velocity

    10.300000       1.325652

     #Tips:主要参数:第一个参数是被运算的数据,第二个参数是所应用的函数,此处是mean函数,最后一个na.rm=T表示要移除缺失值。

    上述情况是不同变量的相同操作,如果是对不同组的相同变量操作,应该怎么实现呢?

    tapply()函数用来创建表格(用“t”标识),该表由函数关于第二个参数定义的子组上的返回值构成,其中子组参数可以是一个因子或者一列因子。后一种情形生成一个交叉分类表。

    我们采用一个三种类型通风的红细胞叶酸浓度的例子(red.cell.folate):

    > red.cell.folate

    > attach(red.cell.folate)

    > tapply(folate,ventilation,mean)

    N2O+O2,24h  N2O+O2,op     O2,24h

    316.6250   256.4444   278.0000

    #Tips: tapply()调用提取folate变量,根据ventilation变量分组,然后对每一组计算均值。这里计算的对象是第一个参数变量。

    同样的方法,标准差和每组中变量的数目都可以计算得到:

    > tapply(folate,ventilation,sd)

    N2O+O2,24h  N2O+O2,op     O2,24h

    58.71709   37.12180   33.75648

    > tapply(folate,ventilation,length)

    N2O+O2,24h  N2O+O2,op     O2,24h

    8          9          5

    我们可以让他们汇总在一起:

    > xbar<-tapply(folate,ventilation,mean)

    > s<-tapply(folate,ventilation,sd)

    > n<-tapply(folate,ventilation,length)

    > cbind(mean=xbar,sd=s,n=n)

                   mean     sd    n

    N2O+O2,24h 316.6250  58.71709  8

    N2O+O2,op  256.4444  37.12180  9

    O2,24h     278.0000  33.75648  5

    #Tips:其中cbind是在R语言系列1里我们提到的,唯一没有提的是里面的参数命名,等号前是名称,等号后接的是变量。

    还是上个部分的数据集juul我们这次来计算igf1的均值,但是要按照tanner分组:

    > juul$tanner<-factor(juul$tanner,labels=c("I","II","III","IV","V"))

    > attach(juul)

    > tapply(igf1,tanner,mean)

      I    II   III   IV   V

     NA  NA  NA  NA  NA

    显然,同样的,这个方式是不能忽略缺失值的。那么需要添加参数na.rm=T:

    > tapply(igf1,tanner,mean,na.rm=T)

    I       II      III       IV        V

    207.4727  352.6714  483.2222  513.0172  465.3344

    ② 函数aggregate()和by()是类似的两个函数。前一个类似tapply(),只是它对整个数据框操作并且把结果作为一个数据框显示。同时显示多个变量是很有用的。比如:

    > aggregate(juul[c("age","igf1")],list(sex=juul$sex),mean,na.rm=T)

    sex      age     igf1

    1   1  15.38436  310.8866

    2   2  14.84363  368.1006

    #Tips:这里的分组参数必须是一个列表(下面有特例),哪怕他是一维列表。列表元素的名称通常作为输出结果列的名称。由于函数应用于整个数据框,所以可以选择数据框的子集进行运算,这里是选择了数值变量。

    #Tips:其中list()里等号左边的sex只是命名,可以省去,并且分组参数,可以使用juul["sex"]来代替list(sex=juul$sex),效果是一样的。数据框类似于列表。

    by()函数也是类似的,不同之处在于函数by()只能把整个数据框作为它的变量,不能使用mean,sd等函数,但是可以通过不同分组汇总。

    > by(juul[c("age","igf1")],juul$sex,summary,na.rm=T)

    #Tips:by()函数的结果是一个列表。

    B. 分组数据作图

    在处理分组数据的时候,我们不仅要对每组作图,并且要把他们放在一起作比较之用。之前我们通过一些作图函数如par()来强行将多个图汇集到一起,但是这里有些函数在显示多组数据时有一些独有的特征。

    01

    直方图

    之前我们已经使用过hist()函数来得到一个简单的直方图,R可以根据数据选择合适的分割。同时也可以通过breaks来设定区间数量。

    我们这里选取R里的关于两组妇女24小时能量消耗的energy数据集,以0.5MJ的倍数作为分割点。

    首先获取我们的数据集

    > attach(energy)

    > expend.lean<-expend[stature=="lean"]

    > expend.lean

    > > expend.obese

    #Tips:我们把energy数据结构中的expend变量根据stature因子的值分割成了两个向量存放在两个变量里。

    下面我们开始作图:

    > par(mfrow=c(2,1))

    > hist(expend.lean,breaks=10,xlim=c(5,13),ylim=c(0,4),col="white")

    > hist(expend.obese,breaks=10,xlim=c(5,13),ylim=c(0,4),col="grey")

    > par(mfrow=c(1,1))

    #Tips:设置>par(mfrow=c(2,1)),从而在一个图里得到两个直方图。Breaks设置成10,代表分割成10条柱,xlim和ylim设定x轴和y轴上下界,col规定颜色。其实像这种直接作图如果需要作出多组数据的结果,可以尝试用脚本来一步操作更加便捷,更改数据不需要一步一步修改。 

    02

    并联箱式图

    如果你想做一个箱式图来展示数据情况的话,我们可以直接处理,不需要对数据先分组。当然,如果你愿意也可以分组作图,这两种方式都是可以的。比如:

    > boxplot(expend~stature)

    或者可以基于单独的向量作图。这种情况下,所用的语句应该指定向量作为两个独立的参数:

    > boxplot(expend.lean,expend.obese)

    #Tips:这两者的差别只是x轴的标识。前一个里有一个“~”y~x前后的两个元素关系是用x表达y。这是我们在模型公式里经常看到的符号。之后在回归方程的建立过程中经常使用。

    03

    带状图

    带状图(stripchart)是最简单但非常有用的一种图,一些分析师称其为点图。带状图可以让我们了解每个点的分布情况,可以很好的排除样本量小的影响。

    > opar<-par(mfrow=c(2,2),mex=0.8,mar=c(3,3,2,1)+0.1)

    > stripchart(expend~stature)

    > stripchart(expend~stature,method="stack")

    > stripchart(expend~stature,method="jitter")

    > stripchart(expend~stature,method="jitter",jitter=0.03)

    > par(opar)

    #Tips:par()函数除了可以设置图形的布局之外,还可以利用mex来设置行间距,mar设置图形区域周边的线的数量。同时par()的设定也可以存储在一个变量(opar)里,以便下次直接调用特定的设置> par(opar)。

    #Tips:第一幅图是标准的带状图,点被绘制到一条线上。这样就会出现重叠而看不见的问题。而method参数就可以调整这个问题。比如“stack”,“jitter”。

    #Tips:右上角的图是设置成”stack”的形式,但是你会发现像8.08,8.09和8.11这样的数据仍然有重叠,也是几乎画在了一个点上。“jitter”则是将所有的点偏置一个垂直的随机量。左下角是标准的jitter参数图,跳动分离明显;如果更倾向于将数据按照水平放置可以设置jitter的值小于默认值0.1。就像右下角那样。

    这部分就是分组数据的描述统计和绘图了。我们已经学习了单组和多组连续数据的汇总和图形展示,下个部分就是分类数据和表格的展示了,敬请期待。

    参考资料:
    1. 《R语言统计入门(第二版)》 人民邮电出版社  Peter Dalgaard著
    2. 《R语言初学者指南》 人民邮电出版社  Brian Dennis著
    3. Vicky的小笔记本《blooming for you》         by Vicky

    End

    相关文章

      网友评论

        本文标题:R语言系列第三期:②R语言多组汇总及图形展示

        本文链接:https://www.haomeiwen.com/subject/kyviiqtx.html