第二章第二节 R语言因子与列表

     R语言的因子实现统计功能,因此称为R语言的先锋不为过份。因子用以数据分类,它有两个内容,一是数据,二是数据的分类,称为水平levels。列表类似C语言的结构struct,元素可选择任意数据结构,是R语言数据结构在类型上的“开拓”。

2.4.1 因子factor

分类变量刻画数据的细分属。统计分析常用分类,R中称为因子(factor)。因子应用统计学的名义变量(nominal variable)和有序变量,功能是记载数据的分组和分类,是R语言统计功能的基础。因子有辅助信息水平(levels)作为分类集合,因子的元素是不同值的levels集元素。水平可为分类设置有意义的标签。

因子的水平是分类信息,然而分类并不表示有序,例如:疾病有循环系统、肺部、消化系统疾病,没有先后、程度、轻重的区别,称为名义型类别变量。而人的健康有疾病、疲劳(亚健康)、健康、身体素质好,这四种程度是有顺序的。因此因子具有普通因子和有序因子两个类型。

应用因子生成更有意义的summary()统计信息。

1.创建因子

    函数factor()创建数据集所有元素的分类。为数据框创建因子是良好的编程习惯,创建向量的因子的标准格式:

    factor(vector,levels=c(),ordered=TRUE)

参数levels定义水平集合,是一个整数向量,ordered表示有序分类,区分普通因子和有序因子。

eg1.创建向量的因子

>dv1=c(1,10,13,10)

>df1=factor(dv2)   #factor()将dv1向量的元素进行分类,创建因子df1

>df1   

[1] 1 10 13 10   #因子的元素

levels: 1 10 13   #levels集

>str(df1)    #df1的内部结构

 Factor w/3 levels:”1” “10” “13”:1 2 3 2  #分成三类:1,10,13  

    as.factor()可将数据转换为因子。

2.数据管理

     length()是因子的长度,保存因子元素的数量而不是levels集的数量。

3.因子的操作

(1)设置有意义的levels集元素

当一个向量不允许有重复值时,因子可以查看分类的错误。

eg2.1 levels()提取水平的名称

>pain=c(0,3,2,2,1)  #《R语言统计入门》p15的例子,对医学数据的操作

>fpain=factor(pain,levels=0:3)  #创建pain的因子,水平的编码0:3

>levels(fpain)=c("none","mild","medium","severe")

以上例题为因子fpain的水平设置有意义的标签,则fpain的元素将用标签代替。

(2)因子元素与分类的关系

eg2.2 因子的操作

>fpain

[1] none severe medium medium mild

Levels: none mild medium severe

>as.numeric(fpain)  #将fpain的元素转换为整数

[1] 1 4 3 3 2       #数值从1开始

>levels(fpain)

[1] "none","mild","medium","severe"

以上程序表明as.numeric()只能转换因子fpain的元素,却不能处理levels集。

(3)分类水平的合并

    若某一个分类的观测少不能有效统计,则将两个水平合并到一个新的因子水平中。

>ftpain1=fpain

>levels(fpain)=list(none="none",

                intermediate=c("mild","medium"),

                severe="severe")   #合并分类用列表实现

>levels(fpain)

[1] "none","intermediate","severe"

(4)有序因子

eg3.创建医学数据的有序因子

>patientID=c(1,2,3,4)  #每个病人的ID号不同

>statu=c(“Poor”,”Excellent”,”Improved”,”Improved”)         #病情

>patientdata=data.frame(patientID,statue)  #先建立数据框,再建立因子

>fstat=factor(statu,levels=c(“Poor”,”Improved”,”Excellent”),ordered=TRUE)

                          #有序因子,词语是有序的

>str(fstat)

 ord.factor w/ 3 levels "Poor"<"Improved"<..: 1 3 2 2  #”<”表示有序因子

>patiendata$fstat=fstat

> summary(patientdata)  #summary()中可知每个分类的元素数量

   patientID          status        fstatu  #有序因子

 Min.   :1.00     Excellent:1      Poor    :1    #有一个病人情况不好

 1st Qu.:1.75      Improved :2     Improved :2    #两个病人病情好转

 Median :2.50     Poor    :1      Excellent:1    #有一个病人几乎痊愈

 Mean   :2.50                             

 3rd Qu.:3.25                             

 Max.   :4.00

> unclass(patientdata)

$patientID

[1] 1 2 3 4

$status??????????

[1] Poor   Excellent Improved  Improved

Levels: Excellent Improved Poor

$fstat

[1] Poor   Excellent Improved  Improved

Levels: Poor < Improved < Excellent

参数ordered很有意义,应掌握使用方法。

3.因子的应用

(1)数据框设置因子变量

在数据框中生成重要的变量的因子,为接下来的数据分析做好准备。

将ISwR软件包的医学数据集thuesen的血糖含量设置分类{1,2,3,4,5,6,7,8,9,10,11,12},1对应[0,1.0)的变量值,...,12对应[11.0,12.0)。了解血糖的范围可用函数range()。源程序见eg4.

eg4.设置数据框变量的因子

>library(ISwR)

>data(thuesen)

>dim1=dim(thuesen)

>dim1

[1] 24  2

>thuesen

##          blood.glucose  short.velocity

##1           15.3           1.76

##2           10.8           1.34

##3            8.1           1.27

##4           19.5           1.47

##5            7.2           1.27

##6            5.3           1.49

##7            9.3           1.31

##8           11.1           1.09

##9            7.5           1.18

##10          12.2           1.22

##11           6.7           1.25

##12           5.2           1.19

##13          19.0           1.95

##14          15.1           1.28

##15           6.7           1.52

##16           8.6            NA

##17           4.2           1.12

##18          10.3           1.37

##19          12.5           1.19

##20          16.1           1.05

##21          13.3           1.32

##22           4.9           1.03

##23           8.8           1.12

##24           9.5           1.70

>range(thuesen[1])

[1]  4.2  19.5

>levels=seq(4,20,1)  #4,20是range的整数

>levl=length(levles)

>ln=dim1[1]

>fthues=factor(1:ln,levels)

>fthues

##[1] <NA> <NA> <NA> 4    5    6    7    8    9    10   11   12   13   14 

##[15] 15   16   17   18   19   20   <NA> <NA> <NA> <NA>

Levels: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

> typeof(fthues) #数据类型

[1] "integer"

> class(fthues)  #类型

[1] "factor"

> str(fthues)  #fthues内部结构

 Factor w/ 16 levels "4","5","6","7",..: 12 7 5 16 4 2 6 8 4 9 ...

                  #可用循环语句实现而不是简单罗立

>for(i in 1:levl-1)    #i是向量levels的下标,不可与levels元素的值混淆

                  #i=1,levels[i]=4;i=2,levels[i]=5

logthes=thuesen$blood.glu<levels[i+1]$thuesen$blood.glu>=levels[i]

                  #logthes是逻辑向量,表示下标有效的逻辑值

                  #levels[levl]=20是为编程设置的一个值,无实际意义

fthues[logthes]=levels[i] 

                  #fthues[logthes]不等于levels的下标i,应仔细不可疏忽

}

>fthues

##[1] 15 10 8  19 7  5  9  11 7  12 6  5  19 15 6  8  4  10 12 16 13 4  8  9

##Levels: 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

>fthues=factor(fthues,levels=seq(4,19,1),ordered=TRUE)

>str(fthues)

 ord.factor w/ 16 levels "4"<"5"<"6"<"7"<..: 12 7 5 16 4 2 6 8 4 9 ...

>thuesen$fthues=fthues 

>summary(thuesen)

 blood.glucose      short.velocity      fthues    #因子fthues频数的统计

 Min.   : 4.200     Min.   :1.030       8      : 3 

 1st Qu.: 7.075      1st Qu.:1.185        4      : 2 

 Median : 9.400     Median :1.270       5      : 2 

 Mean   :10.300    Mean   :1.326     6      : 2 

 3rd Qu.:12.700     3rd Qu.:1.420       7      : 2 

 Max.   :19.500     Max.   :1.950     9      : 2 

                      NA's   :1       (Other):11    

对数据框的变量设置因子,可用summary()统计每一类的元素数量,并且可应用tapply()函数对每一个进行相同的计算f()。

(2)线性回归的应用

因子在线性回归函数的数据拟合中应用,使得输出变短。因子的统计信息可用汇总统计函数summary()表示。函数summary()体现数据框所有变量的汇总信息,显示数值连续型变量的最小值、最大值、均值和各四分位数,factor变量各水平的频数值。因此,因子变量的应用在线性回归函数lm()的统计信息中,可使输出更短小精悍。

>summary(thuesen)

4.因子的函数

unclass()显示因子的分类,而且有attr()等。

>unclass(df1)

[1] 1 2 3 2

>unclass(fthues)

>unclass(pathtiendata$fstatu)

5.tapply()应用和factor因子

eg5. tapply(data,index,f())的应用

> ages <-c(26,28,56,38,25,42) 

> affits <-c("R","D","D","R","U","D")  #用途类似levels,但是没有生成factor

>tapply(ages,affits,means)  #应用affits对ages向量进行分类,计算每类的means

     D     R    U

    42    32   25

函数tapply()把向量affits当作因子,levels={"D","R","U"},”D”出现在下标2,3,6的位置,”R”出现在1,4的位置,”U”出现在5。因此,ages向量的分组是(26,55,42),(25,37),(21)。然后,tapply()对所有分组计算means均值,分别是41,31,21。此编程方法是对数据设置向量作为因子,因此并不是根据数据的可管理特性应用factor()进行分类,而是根据实际应用的要求。不能用factor()对向量元素进行分类时可用此方法,但是对大量数据设置每个元素的分类则很费力,例如ISwR软件包的thuesen数据集。

函数tapply()的功能是,根据分类向量levels分组数据向量data,可得到多个分组数据,然后对所有分组应用函数f()。因此tapply()函数可不需要对数据框的不同变量应用计算f(),而是对不同长度的分组数据应用计算f()。 

2.4.2 列表list

列表(list)像C的结构struct或python语言的字典类型。列表的组件(components)称为分量或元素,组件名则为标签tags。R语言数据框和面向对象编程的基础是列表。列表元素的长度可不相同,类型可是单元素或者列表,因此在递归型recursive数据结构的基础上看,列表是数据结构中的广义表。

1. 创建列表

    函数list()创建不同部件组成的列表,分量可以是不同类型和长度的向量、矩阵、数据框、列表。列表是R语言多数函数的返回值类型,因此R语言函数可返回多个值组成一个列表,与C语言不同。list()的标准格式:

    list(tag1=compon1,tag2=compon2,...,tagR=componR)

    列表的常用应用有多维数组的标签,添加数据框的观察,以及构成实际的报表格式。创建列表还可用函数vector(),参数mode=list。

eg1.三维数组标签的产生

      dim1=c(“A1”,”A2”,”A3”)

      dim2=c(“B1”,”B2”)

      dim3=c(“C1”,”C2”,”C3”)

      dimnames=list(dim1,dim2,dim3)

eg2.列表构成的报表

      报表名称:一个字符串,gs=”This is 2016 fist list”

      报表的主要对象:一个数值型向量,ha=c(20,29,39,43)

      报表的主要内容:一个矩阵,salaryM=matrix(1:10,nrow=5)

      报表的注释:一个字符型向量,notes=c(“one”,”two”,”three”)

则,生成报表,dlist1=list(Title=gs,age=ha,salaryM,notes)。

只有前两个组件有标签。组件的编号又称为索引。? 

eg3.用vector()创建列表,因为列表是向量。

>dlist2=vector(mode=list)

>dlist2[["events"]]=c("writing Docx ","studying","research")

>dist2

$events

[1]  "writing Docx"  "studying"   "research" 

2.数据管理

    数据类型 mode()、列表组件个数 length()、获得标签 names()。

3.列表组件的访问

   选取列表组件的方法有三个,list$标签,list[["标签"]],list[[组件编号]]。若要访问分量中的元素,则用list[[组件编号]][元素下标范围s:t]或list$[组件名][s:t]。元素下标范围同样可用条件选择的方法。

>dlist2[[1]]

[1]  "writing Docx"  "studying"   "research" 

>dlist2[[1]][2:3]

[1]  "studying"   "research" 

 

4.数据操作

(1)增加列表组件

方法一,组件赋值dlist2$timecha=c("Lqm","Lih","Sh"),方法二,组件下标索引赋值dlist2[[3]]=c(20,20,20,100,100,30),则列表dlist2有三个组件。

(2)删除列表元素

    将列表组件设置为NULL,应注意此元素后面组件的下标索引都减1。

(3)生成子列表[]

    用list["标签"]和list[组件编号]返回子列表,而list[[]]访问组件,返回组件的类型。

>dlist3=dlist2[2]   #此方法类似数据框[列下标]

>class(dlist3)

[1]  "list"

>dlist3

$timecha

[1]  "Lqm"  "Lih"  "Sh"

(4)c()拼接合并多个列表

   然而c()合并的列表中,组件的层次相同。若要保持组件是一个列表,应用list()更恰当。

>dlist4=c(list("tomorrow",2016-10-19,5),list(read,writing))  

>class(dlist4)

[1]  "list"

>length(dlist4)

[1] 5

>dlist4

>str(dlist4)

>dlist5=list(list("tomorrow",2016-10-19,5),list(read,writing))

>str(dlist5)

 

5.列表的函数

(1)unlist()

    unlist()把列表转换为向量,获取列表的值,而且此向量的元素有标签。去掉元素标签用函数unnames()。若列表元素是字符串则unlist()的返回值是字符串,若列表元素都是数值型则产生数值向量。若两类元素都有或者列表元素类型不同,则执行强制转换,生成大多数元素的类型,例如字符串。

>dv1=unlist(dlist4)

>class(dv1)

[1] character

>length(dv1)

[1] 5    

6.应用apply族函数 

 

7.类型转换

    is.recursive(x)可判断列表是否递归类型。Is.list()可发现函数的返回值是否列表。as.list()转换产生列表。

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值