4.2 函数 tapply() 和不规则数组
沿用前面的例子,假定我们有这些税务会计师的收入信息并且保存在另外一个向 量中(适当的货币单位)
> incomes <- c(60, 49, 40, 61, 64, 60, 59, 54, 62, 69, 70, 42, 56, 61, 61, 61, 58, 51, 48, 65, 49, 49, 41, 48, 52, 46, 59, 46, 58, 43)
为计算样本中每个州的平均收入,我们可以用函数 tapply()
:
> incmeans <- tapply(incomes, statef, mean)
这将给出一个均值向量。各个元素都用对应的水平名字(levels)标记。
act nsw nt qld sa tas vic wa
44.50000 57.33333 55.50000 53.60000 55.00000 60.50000 56.00000 52.25000
函数 tapply()
将一个功能函数(这里是 mean()
)用于第二个参数(这里是statef)1定义于第一个参数(这里是incomes)上得到的所有组。此时,各个组的数据好像是独立的向量。得到的结果向量长度和因子的水平数一致。读者可以通过帮助文档获得更多的信息。
假定我们进一步想计算各个州的标准误(standard error)2。我们可以写一个 R 函数来计算任一给定向量的标准误。既然已经有内置函数 var()
计算样本方差,则这个函数可以在一行写完,并且有一个参数等待赋值:
> stderr <- function(x) sqrt(var(x)/length(x))
(编写函数可以参考后面的内容编写你自己的函数部分。这里的写的标准误演示函数其实是没有必要的,因为R有一个内置计算标准误的函数 sd()
3) 赋值后,标准误被计算出来
> incster <- tapply(incomes, statef, stderr)
值分别为
> incster
act nsw nt qld sa tas vic wa
1.500000 4.310195 4.500000 4.106093 2.738613 0.500000 5.244044 2.657536
作为一个练习,你可以计算一下州平均收入的95%信度区间。提示一下,你可能要再次使用 tapply()
和能得到样本量的函数 length()
,以及能得到t-分布分位数的函数 qt()
。(你需要参考一下 R 为t-检验设计的函数。)
函数 tapply()
还可以用来处理一个由多个分类因子决定的向量下标组合。例如,我们可能期望通过州名和性别把这税务会计师分类。不过,就在上面最简单的情况中(仅仅一个变量),我们也可以这样考虑这个问题(复杂因子组合时一样处理)。 向量中的值可以根据因子中不同的水平分成许多组。函数就是独立的用于这些组。得到的值是这些函数结果的向量,并且以因子的水平属性标记。
因为子类的大小是不规则的,所以向量和作为标签的因子的组合对象只是我们偶尔会提及的不规则数组(ragged array)一个特例罢了。当子类大小一致的时候,索引最有效,正如我们在下一章中所看到的一样。
1. 注意,当第二个参数不是因子时,函数 tapply() 同样有效,如 tapply(incomes, state)。这对一 些其他函数也是有效,因为必要时 R 会用 as.factor() 把参数强制转换成因子。 ↩
2. 译者注:注意和“标准差”的不同 ↩
3. 译者注: 我觉得这里英文原文弄错了. R 里面的内置函数sd()是用来计算’标准差的‘不是标准误, 大 家可以看看本手册定义的stderr(1:4)和内置的sd(1:4)结果是不是一样. 它们的关系应该是stderr <- function(x){sd(x)/sqrt(length(x))} ↩