R是一门著名的可用于数据和统计分析的程序语言,本文翻译自R软件官方文档教程《An Introduction to R》,仅供学习和参考。
4 有序因子与无序因子
因子factor
是一种类似向量的对象,用于表示分类变量,其元素的长度和类型都要相同。R 提供有序因子和无序因子。虽然因子的“实际”应用是使用模型公式model formulae
,但我们在这里看一个具体的例子。
4.1 一个具体的例子
假设,我们有一个由20名来自全国各省的大学生的数据组成的样本,他们来自的省份由一个字符串向量指定,如下:
> province <- c("江西", "北京", "海南", "湖北", "江西",
+ "海南", "甘肃", "海南", "浙江", "北京",
+ "辽宁", "江西", "海南", "湖北", "北京",
+ "浙江", "北京", "江西", "甘肃", "辽宁")
> province
[1] "江西" "北京" "海南" "湖北" "江西" "海南" "甘肃" "海南" "浙江" "北京" "辽宁" "江西"
[13] "海南" "湖北" "北京" "浙江" "北京" "江西" "甘肃" "辽宁"
请注意,在字符串向量的情况下,“排好了序”表示按字母顺序排序。
使用 factor()
函数可以类似地创建一个因子对象factor
:
> provinceFactor <- factor(province)
> provinceFactor
[1] 江西 北京 海南 湖北 江西 海南 甘肃 海南 浙江 北京 辽宁 江西 海南 湖北 北京 浙江 北京
[18] 江西 甘肃 辽宁
Levels: 北京 甘肃 海南 湖北 江西 辽宁 浙江
注意到,print
函数(即控制台)将以与普通向量稍微有点不同的方式打印因子对象。
为了单独显示或获取Levels
,可以调用levels()
函数。Levels
表示因子中的不同值:
> levels(provinceFactor)
[1] "北京" "甘肃" "海南" "湖北" "江西" "辽宁" "浙江"
4.2 tapply()函数和不规则数组
继续前面的例子,假设我们在另一个向量中指定这些大学生的成绩:
> grades <- c(90,88,76,89,93,80,82,72,98,87,
+ 77,91,87,99,82,91,77,74,70,90)
> grades
[1] 90 88 76 89 93 80 82 72 98 87 77 91 87 99 82 91 77 74 70 90
为了计算各个省份学生成绩的样本平均数,我们现在可以使用tapply()
函数:
> gradesMeans <- tapply(grades,province,mean)
> gradesMeans
北京 甘肃 海南 湖北 江西 辽宁 浙江
83.50 76.00 78.75 94.00 87.00 83.50 94.50
我们可以看到,tapply()
函数返回了一个用Levels
标记好了的向量,分别表示各个省学生的平均成绩。
tapply()
函数用于将某个函数(此处为mean()
)应用于第一个参数(此处为grades
)的某些部分,这些部分由第二个参数(此处为province
)的Levels
划分。在这里,就是求每个省份的平均的成绩。结果的长度与第二个参数的Levels
的长度相同。详细内容可参看tapply()
的帮助文档。
进一步,假设我们需要计算各省份学生成绩的标准误差。为此,我们需要自己来编写一个 R 函数来计算任何给定向量的标准误差。由于有一个内置函数 var()
来计算样本方差,因此这样的函数是一个非常简单的一行:
stdError <- function(x) sqrt(var(x) / length(x))
自定义函数将在之后详细介绍。
现在,我们可以用tapply()
函数来计算各个省学生平均成绩的标准误差。
> gradeStdErr <- tapply(grades, province, stdError)
> gradeStdErr
北京 甘肃 海南 湖北 江西 辽宁 浙江
2.533114 6.000000 3.198307 5.000000 4.377975 6.500000 3.500000
作为练习,您还可以计算各省平均成绩的95%置信区间。为此,您可以再次使用tapply()
函数,并使用length()
函数获取样本的大小,紧接着使用qt()
函数找到适当的t分布百分点。(您可以自行研究R进行t检验的工具)。
函数tapply()
也可以用于通过多个类别因子对向量进行更复杂的索引处理。例如,我们可能希望按照省份和性别的不同来分类学生。然而,在我们这个简单例子中(只有一个因子),发生的情况可以如下所述。对于向量中的值,按照因子的值进行分类,分成多个类别组。然后,将函数应用到每个类别组中。返回值是一个函数结果向量,由因子向量的Levels
标记。
向量和标签因子的组合就是所谓的不规则数组ragged array
,因为子类大小可能是不规则的。当子类大小相同时,索引可以隐式完成并更加高效,正如我们在下一节中所见。
4.3 有序因子
因子的Levels
按字母顺序存储,或者按照明确指定的因子顺序存储。
有时,我们想记录Levels
的自然顺序,并希望在我们的统计分析能够利用到它。ordered()
函数创建这种有序因子,但是除此之外与因子factor
相同。就大多数情况而言,有序和无序因子之间唯一的区别是前者打印时会注重Levels
的顺序,另外在拟合线性模型时也有些不同。