第三章第二节 table()与报表

3.2.1 表格table()

分组数据表示的信息用表格描述,表格是双向(two-way)的。分组数据中因子的数量称为频数,table()生成频数表描述因子或数据向量的数值分布概况,相对频数又称为频率。table族函数有marqin.table()计算边际表格,prop.table()计算相对频数,addmagins()计算条件频数(边际值)。

table()的另一个功能是对数据框和列表进行多维分组,用多个变量或元素分组另一个变量或元素,结果用逻辑值表示位置上有值,实现将变量数据分组到高维数组的不同层。因此,高维数组和table()有关联。table()的函数有dimnames()获得维度的名称和水平值。

eg1.计算数字出现的相对频数

>dv1.1=c(22,23,24,22,23,23,12,13,14,14,14,23,23,22)

>dv1.2=c(14,23,13,13,12,13,13,22,12,11,22,21)

>dv1=c(dv1.1,dv1.2)
>dtable1=table(dv1)

>dtable1

11 12 13 14 21 22 23 24

 1  3  5  4  1  5  6  1
>dv2=as.vector(dtable1)

[1] 1 3 5 4 1 5 6 1
>dtable2=prop.table(dtable1)

dv1

        11         12         13         14         21         22         23

0.03846154 0.11538462 0.19230769 0.15384615 0.03846154 0.19230769 0.23076923

        24

0.03846154
>dv3=as.vector(dtable2)

> dv3

[1] 0.03846154 0.11538462 0.19230769 0.15384615 0.03846154 0.19230769

[7] 0.23076923 0.03846154

>dafr1=data.frame(dv2,dv3)

> dafr1

  dv2        dv3

1   1 0.03846154

2   3 0.11538462

3   5 0.19230769

4   4 0.15384615

5   1 0.03846154

6   5 0.19230769

7   6 0.23076923

8   1 0.03846154

    看到编号不容易理解,则将编号替换为数字:
>dimnames(dafr1)=list(c('11','12','13','14','','21','22','23','24'),c("频数","频率"))

> dafr1

   频数       频率

11    1 0.03846154

12    3 0.11538462

13    5 0.19230769

14    4 0.15384615

21    1 0.03846154

22    5 0.19230769

23    6 0.23076923

24    1 0.03846154

    tapply()帮助文件中的例题比较table()与tapply()的不同,包括对因子向量分类,用因子向量分类数据向量用法的比较等。

eg2.tapply()与table()统计groups分类后的频数

>require(stats)
>groups=as.factor(rbinom(32, n = 5, prob = 0.4))   #创建因子

               #二项分布B(5,0.4)的32个随机数

>groups
##[1] 15 13 13 16 12
##Levels: 12 13 15 16

>tapply(groups, groups, length) #对groups进行分类,应用length()

##12 13 15 16
##1  2  1  1

>table(groups)  #比较table(),对同一个向量分类的频数计算相同
##groups
##12 13 15 16
## 1  2  1  1

    tapply()是建立在table()上,对分组应用函数。

eg3.tapply()与table()用因子对数据向量分类的用法比较
>n=17

>fac=factor(rep(1:3, length=n), levels=1:5)  #fac是因子

> fac

[1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2

Levels: 1 2 3 4 5

> dv1=tapply(1:n,fac,length)   #分类{1,2,...,n},统计分组数据的数量

> dv1

 1  2  3  4  5   #按位置分类,对应因子相同的元素则是同一类

 6  6  5 NA NA

> dv2=tapply(1:n, fac, sum)  #分类数据向量,计算分组数据的总值

> dv2

 1  2  3  4  5

51 57 45 NA NA
> tapply(1:n, fac, sum, simplify = FALSE) #输出列表

$`1`

[1] 51

$`2`

[1] 57

$`3`

[1] 45

$`4`

NULL

$`5`

NULL

> range(1,2,3)  #分析range()的用法,数据范围i

[1] 1 3

> range(1,2,3,1,2,3)

[1] 1 3

> tapply(1:n, fac, range) #对分类数据是每一类的范围

$`1`

[1]  1 16

$`2`

[1]  2 17

$`3`

[1]  3 15

$`4`

NULL

$`5`

NULL

> range(1:n)

[1]  1 17

> dv=1:n

> tapply(dv,fac,range)

$`1`

[1]  1 16

$`2`

[1]  2 17

$`3`

[1]  3 15

$`4`

NULL

$`5`

NULL

 > range(dlist)  #dlist范围不变

[1]  1 17

> dv1=11:27

> dlist1=split(dv1,fac)

> dlist1

$`1`

[1] 11 14 17 20 23 26

$`2`

[1] 12 15 18 21 24 27

$`3`

[1] 13 16 19 22 25

$`4`

integer(0)

$`5`

integer(0)

> lapply(dlist1,range) #range()仍然是数据向量范围

$`1`

[1] 11 26

$`2`

[1] 12 27

$`3`

[1] 13 25

$`4`

[1]  Inf -Inf

$`5`

[1]  Inf -Inf

eg4.对列表或数据框建立表格,与tapply()的比较
>ind=list(c(1, 2, 2), c("A", "A", "B"))
>table(ind)  

      ind.2
ind.1 A B
    1 1 0
    2 1 1
    用c("A", "A", "B"))分类c(1, 2, 2),则在"A"位置上有{1,2},而在"B"位置上只有{2}。建立双向表格,是二维逻辑值表格。

>tapply(1:3, ind)  # 用列表ind分组向量1:3

[1] 1 2 4

> tapply(c(0,0,0),ind)

[1] 1 2 4

    表明输出与数据向量没有元素的关系,因此是位置的记录。用ind的table()形式分组,则在table()的对应位置有元素,因此按列输出元素下标。
>tapply(1:3, ind, sum)  #形式是table(),所以

   A  B
1 1 NA
2 2  3

> ind1=list(c(1,2,2),c(2,2,4))  #分组效果与ind相同

> tapply(c(1,1,1),ind1)

[1] 1 2 4

> ind1=list(c(1,2,2),c(2,2,4),c(4,4,5))  #三个元素的列表

> tapply(c(1,1,1),ind1)

[1] 1 2 8

   在ind1的table()形式分组,输出元素的下标。

> table(ind1)   #建立列表ind1的table()

, , ind1.3 = 4   #在4的位置分类

      ind1.2

ind1.1  2 4

     1 1 0

     2 1 0

, , ind1.3 = 5

      ind1.2

ind1.1  2 4

     1 0 0

     2 0 1

    与4相同行列c(1,2),c(2,2),所以ind1.2的4对应位置为0。然后再分组ind1.2的2对应ind1.2的两个元素。在5的位置相同行列元素c(2),c(4),然后再分组,ind1.2的4的位置有ind1.2的2。c(1,2,3)分组后下标分别是c(1,2,8)。

eg5.对学生分组没有按照分数等级,而是其他方法

> class=c(1,2,3,2,1,2,1,3)

> class
[1] 1 2 3 2 1 2 1 3

> student=c(81,65,72,88,73,91,56,90)
>student

[1] 81 65 72 88 73 91 56 90

>class=factor(class)  

> tapply(student,class,mean)
       1        2        3
70.00000 81.33333 81.00000
> tapply(student,class)

[1] 1 2 3 2 1 2 1 3

> tapply(student,class,min)
 1  2  3
56 65 72
> tapply(student,class,max)
 1  2  3
81 91 90
> table(class)
  class
 1 2 3   #对class进行分组

 3 3 2

> dar1=table(student,class)  #class对student分组

> dar1

       class

student  1 2 3

     56 1 0 0

     65 0 1 0

     72 0 0 1

     73 1 0 0

     81 1 0 0

     88 0 1 0

     90 0 0 1

     91 0 1 0

> class(dar1)  #dar1的类型是table而不是矩阵

[1] "table"

> dim(dar1)

[1] 8 3

> str(dar1)     #dar1有两个成员

 'table' int [1:8, 1:3] 1 0 0 1 1 0 0 0 0 1 ...

 - attr(*, "dimnames")=List of 2

  ..$ student: chr [1:8] "56" "65" "72" "73" ...

  ..$ class  : chr [1:3] "1" "2" "3"

> typeof(dar1)

[1] "integer"

> mode(dar1)

[1] "numeric"

> dar1$student  #dar1不能用$得到分量

Error in dar1$student : $ operator is invalid for atomic vectors

> dar1[1]

[1] 1

> dar1[2]

[1] 0

> dar1[1,]  #访问第一行,与数据框相同

1 2 3

1 0 0

> dar1[,1]  #访问第一列,与数据框相同

56 65 72 73 81 88 90 91

 1  0  0  1  1  0  0  0

 3.2.2 aggregate()

    整合函数aggregate()用因子组合折叠(叠加)数据框,对数据框的分组数据应用函数f()。参数by用列表设置因子组合。把结果组合成表格返回。tapply()只能对一个变量的分组数据应用函数,因此返回向量。而函数by()对数据框的子集应用函数,而数据框的子集是一维的,实际上by()是tapply()对数据框的应用。

    编程格式:

aggregate(data,by,f())

根据data的数据类型不同有三种用法,

1. data=data.frame是数据框

aggregate(data, by, FUN, ..., simplify = TRUE) 

2.data=formula是公式

aggregate(formula, data, FUN, ..., subset, nana.action = na.omit) 

3.data=ts是时间序列

   aggregate(ts, nfrequency=1, FUN=sum, ndeltat =1, ts.eps=getOption("ts.eps"), ...) 

eg6.1 数据集mtcars用cyl分组所有变量计算mean

 >aggregate(mtcars,list(mtcars$cyl),mean)

  Group.1      mpg  cyl     disp        hp      drat       wt      qsec

1       4  26.66364   4  105.1364   82.63636  4.070909  2.285727  19.13727

2       6  19.74286   6  183.3143  122.28571  3.585714  3.117143  17.97714

3       8  15.10000   8  353.1000  209.21429  3.229286  3.999214  16.77214

          vs        am      gear     carb

1  0.9090909  0.7272727  4.090909  1.545455

2  0.5714286  0.4285714  3.857143  3.428571

3  0.0000000  0.1428571  3.285714  3.500000

    叠加Group.1表示汽缸数cyl,则拥有4个气缸的汽车每加仑汽油行驶公里数均值是26.66364.(空天,兰月亮,网络)

eg6.2 数据集mtcars用cyl和hp分组所有变量计算mean

>aggregate(mtcars,list(mtcars$cyl,mtcars$gear),mean)

   Group.1  Group.2   mpg  cyl     disp       hp     drat       wt     qsec   vs

1       4       3  21.500   4  120.1000  97.0000  3.700000  2.465000  20.0100 1.0

2       6       3  19.750   6  241.5000 107.5000  2.920000  3.337500  19.8300 1.0

3       8       3  15.050   8  357.6167 194.1667  3.120833  4.104083  17.1425 0.0

4       4       4  26.925   4  102.6250  76.0000  4.110000  2.378125  19.6125 1.0

5       6       4  19.750   6  163.8000 116.5000  3.910000  3.093750  17.6700 0.5

6       4       5  28.200   4  107.7000 102.0000  4.100000  1.826500  16.8000 0.5

7       6       5  19.700   6  145.0000 175.0000  3.620000  2.770000  15.5000 0.0

8       8       5  15.400   8  326.0000 299.5000  3.880000  3.370000  14.5500 0.0

    am  gear     carb

1  0.00    3  1.000000

2  0.00    3  1.000000

3  0.00    3  3.083333

4  0.75    4  1.500000

5  0.50    4  4.000000

6  1.00    5  2.000000

7  1.00    5  6.000000

8  1.00    5  6.000000

在结果中,折叠group.1cyl和group.2 gear挡位数两组分类“因子”,产生8个数据框分组数据,例如汽车的汽缸数是4,挡位数是5,则每加仑汽油行驶公里数均值是28.200,是所有分组中的最大值,表明此车型性能最好。

若对数据框的变量子集应用分类因子分组,则可用formular公式或表达式的方式,~表示因子组合。

>aggregate(cbind(mtcars$mpg,mtcars$hp)~mtcars$cyl+mtcars$gear,FUN=mean)

   #cylgear因子组合分类变量mpghp组成的新数据框

   mtcars$cyl   mtcars$gear     V1       V2

1          4           3  21.500   97.0000

2          6           3  19.750  107.5000

3          8           3  15.050  194.1667

4          4           4  26.925    76.0000

5          6           4  19.750   116.5000

6          4           5  28.200  102.0000

7          6           5  19.700  175.0000

8          8           5  15.400  299.5000

此命令的结果和下面的命令相同。

> aggregate(mtcars[c("mpg","hp")],list(mtcars$cyl,mtcars$gear),mean)

  Group.1  Group.2    mpg       hp

1       4       3  21.500  97.0000

2       6       3  19.750 107.5000

3       8       3  15.050 194.1667

4       4       4  26.925  76.0000

5       6       4  19.750 116.5000

6       4       5  28.200 102.0000

7       6       5  19.700 175.0000

8       8       5  15.400 299.5000

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值