4. 因子
因子提供一种简单而又紧凑的形式来处理分类数据。因子用level来表示所有可能的取值。对于数据集中取值个数固定的分类数据,因子特别有用,图形函数和汇总函数就充分利用了因子这种优点。
R软件内部以数值编码方式来存储因子值,这将提高内存利用率。举例说明R如何创建因子,假设一个10人的性别向量:
> g <- c("f", "m", "m", "m", "f", "m", "f", "m", "f", "f")
> g
[1] "f" "m" "m" "m" "f" "m" "f" "m" "f" "f"
>
> g <- factor(g)
> g
[1] f m m m f m f m f f
Levels: f m
R是一种函数型编程语言,最常见的应用方式之一是函数复合方式。假设另外5个人需要把性别信息存储在另一个因子对象中。假设都是男性,且与g有相同的因子水平,则必须使用以下命令:
> other.g <- factor(c("f", "f", "f", "f", "f"), levels = c("f", "m"))
> other.g
[1] f f f f f
Levels: f m
上例中把函数c()应用到函数factor()的结果。显然,可以先把函数c()的结果先赋值给一个对象,然后,再用该对象调用factor()函数。这样做有利有弊,好处是避免创建多余的对象浪费内存;缺点是不易阅读。
因子类型数据可做的事情之一是计算每个可能值的发生次数,利用table()函数进行计算:
> table(g)
g
f m
5 5
> table(other.g)
other.g
f m
5 0
table()函数可以获取多个因子的交叉表。假设一个向量a存储10个人所属的年龄,那么可以得到这两个向量的交叉表:
> a <- factor(c('adult', 'adult', 'juvenile', 'juvenile', 'adult', 'adult', 'adult', 'juvenile', 'adult', 'juvenile'))
> table(a, g)
g
a f m
adult 4 2
juvenile 1 3
计算交叉表的边际和相对概率。首先计算上面数据集中性别和年龄因子的总计:
> t <- table(a, g)
> t
g
a f m
adult 4 2
juvenile 1 3
> margin.table(t, 1)
a
adult juvenile
6 4
> margin.table(t, 2)
g
f m
5 5
函数中输入参数“1”和“2”分别代表交叉表t的行和列,即表格t的第一维度和第二维度。然后计算表格t中每个维度的边际和的相对概率:
> prop.table(t, 1)
g
a f m
adult 0.6666667 0.3333333
juvenile 0.2500000 0.7500000
> prop.table(t, 2)
g
a f m
adult 0.8 0.4
juvenile 0.2 0.6
> prop.table(t)
g
a f m
adult 0.4 0.2
juvenile 0.1 0.3
注意:如果需要的是百分比,可以在调用函数时乘以100。
5. 生成序列
R有多种生成序列的方法,归纳起来两大类:
1) 直接设定序列值,并赋值给对象
> x <- 1:10
> x
[1] 1 2 3 4 5 6 7 8 9 10
2) 利用函数生成序列,包括生成有序序列的函数和生成随机序列的函数
用seq( )函数生成有序序列:
> seq(1, 10)
[1] 1 2 3 4 5 6 7 8 9 10
> seq(1, 10, 2)
[1] 1 3 5 7 9
> seq(from = 1, to = 5, length = 4)
[1] 1.000000 2.333333 3.666667 5.000000
> seq(from = 1, to = 5, length = 2)
[1] 1 5
> seq(from = 1, by = 2, length = 10)
[1] 1 3 5 7 9 11 13 15 17 19
seq( )函数中,from为序列起始值,to为序列结束值,length为序列长度(非负值),by为序列增量值。其中from,to,length,by的关系为:
by = (to – from)/(length - 1)
用rep( )函数生成有序序列:
> rep(5) // 不指定重复次数,默认为1
[1] 5
> rep(5, 10) // 指定重复次数为10,相当于times = 10ss
[1] 5 5 5 5 5 5 5 5 5 5
> rep(5, times = 5) // 用times参数指定重复次数s
[1] 5 5 5 5 5
> rep("hi", 4)
[1] "hi" "hi" "hi" "hi"
> rep(1:2, 3) // 参数1相当于一个子序列(1:2s),然后重复生成三次s
[1] 1 2 1 2 1 2
> rep(1:2, each = 3) // each指定子序列(1:2)中每个元素重复生成三次s
[1] 1 1 1 2 2 2
用gl( )函数生成带有因子的序列。函数语法是gl(k, n, length,labels, ordered = FALSEs),其中k是因子水平的个数,n是每个因子重复的次数, length是序列总长度, labels是因子水平向量:
> gl(3 ,5) // 因子水平采用默认向量(1, 2, 3)
[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
Levels: 1 2 3
> gl(2, 5, labels = c("female", "male")) // 指定因子水平向量
[1] female female female female female male male male male male
Levels: female male
> gl(2, 1, 20)
[1] 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2
Levels: 1 2
> gl(2, 2, 20)
[1] 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2 1 1 2 2
Levels: 1 2
R提供多个根据不同概率密度函数来生成不同随机序列的函数。这些函数的通用结构是rfunc(n, par1, par2, …),其中func是概率分布的名称,如正太分布,t分布等;n是要生成的随机数的个数;par1,par2,…是概率密度函数需要的一些参数。如生成10个服从均值为0,标准差为1的正太分布的随机数:
> rnorm(10)
[1] 1.26721972 0.52197054 -0.37588640 0.45649095 0.53208132 0.58825602 0.25304735 -0.14886216
0.77378155 0.03471966
生成4个服从均值为10,标准差为3的正太分布的随机数:
// mean表示均值,默认为0,sd(standard deviation)表示标准偏差,默认为1
> rnorm(4, mean = 10, sd = 3)
[1] 2.768331 15.189744 11.272716 10.329443ss
生成5个服从自由度为10的t分布的随机数:
> rt(5, df = 10) // df(degree of freedom)表示自由度
[1] 0.05874764 0.26098078 1.61894155 0.86475793 1.19027904
6. 数据子集
所谓数据子集就是通过位置、名称等条件,从原来的数据集合中索引出符合条件的数据组成的集合。
除了常规的像数组一样,直接指定位置来获取向量中的某个元素外,R还有多种类型的向量索引:
1) 逻辑值向量索引
> x <- c(0, -3, 4, -1, 45, 90, -5)
> x > 0
[1] FALSE FALSE TRUE FALSE TRUE TRUE FALSE
> x[x > 0]
[1] 4 45 90
x为整数向量,语句2利用循环规则,将每个元素都与0进行比较,生成长度与向量x相同的逻辑值向量。语句3则是利用该逻辑值向量对x进行索引,可以得到TRUE值位置的向量x的元素,也可以理解为:给出逻辑表达式为真的向量x的值。
2) 逻辑索引
利用逻辑运算符及其符合逻辑对向量x中的元素进行索引。
> x[x < -1 | x > 5] // 取并集运算
[1] -3 45 90 -5
> x[x > 40 & x < 100] // 取交集运算
[1] 45 90
3) 整数向量索引
R支持用整数向量来索引向量中的多个元素。整数向量中的数字表示要提取的目标向量的元素的位置,见如下命令:
> x[c(4, 6)]
[1] -1 90
> x[1:3]
[1] 0 -3 4
> y <- c(1, 4)
> x[y]
[1] 0 -1
另外,也可以用一个负值的向量来表示哪些位置的元素可以排除,如:
> x[-1] // 位置1元素排除
[1] -3 4 -1 45 90 -5
> x[-c(4, 6)] // 位置4和位置6元素排除
[1] 0 -3 4 45 -5
> x[-(1:3)] // 位置1、2、3元素排除
[1] -1 45 90 -5
4) 字符串向量索引
欲使用字符串向量索引,首先要使用R提供的names( )函数来给向量中的元素命名。且命名后的元素位置更容易记住,所以有时候命名元素更受欢迎。如下例所示:
> pH <- c(4.5, 7, 7.3, 8.2, 6.3)
> names(pH) <- c("area1", "area2", "mud", "dam", "middle")
> pH
area1 area2 mud dam middle
4.5 7.0 7.3 8.2 6.3
如果向量创建之时,就已经知道向量中位置的名称,则可以用以下方式创建:
> pH <- c(area1 = 4.5, area2 = 7.0, mud = 7, dam = 8.2, middle = 6.3)
现在可通过元素名称字符串向量对pH向量进行索引:
> pH["mud"]
mud
7
> pH[c("area1", "middle")]
area1 middle
4.5 6.3
5) 空索引
当向量x的索引为空时,被视为无任何限制条件,结果就是所有元素都被选中,如下:
> x[]
[1] 0 -3 4 -1 45 90 -5
> pH[]
area1 area2 mud dam middle
4.5 7.0 7.0 8.2 6.3
空索引在我们需要给向量中的所有元素统一赋值时,非常有用,如将向量x中的所有元素赋值为0,可简单写成:
> x[]<- 0 // 向量x的所有元素赋值为0
> x
[1] 0 0 0 0 0 0 0
注意:x[]<- 0区别与x <- 0,后者是创建单一元素(元素值为0)向量,然后赋值给x。