在第4章,我们审视了R中基本的数据集处理方法,本章我们将关注一些高级话题。本章分为三个基本部分。在第一部分中,我们将快速浏览R中的多种数学、统计和字符处理函数。为了让这一部分的内容相互关联,我们先引入一个能够使用这些函数解决的数据处理问题。在讲解过这些函数以后,再为这个数据处理问题提供一个可能的解决方案。
接下来,我们将讲解如何自己编写函数来完成数据处理和分析任务。首先,我们将探索控制程序流程的多种方式,包括循环和条件执行语句。然后,我们将研究用户自编函数的结构,以及在编写完成后如何调用它们。
最后,我们将了解数据的整合和概述方法,以及数据集的重塑和重构方法。在整合数据时,你可以使用任何内建或自编函数来获取数据的概述,所以你在本章前两部分中学习的内容将会派上用场。
5.1 一个数据处理难题
要讨论数值和字符处理函数,让我们首先考虑一个数据处理问题。一组学生参加了数学、科学和英语考试。为了给所有学生确定一个单一的成绩衡量指标,需要将这些科目的成绩组合起来。另外,你还想将前20%的学生评定为A,接下来20%的学生评定为B,依次类推。最后,你希望按字母顺序对学生排序。数据如表5-1所示。
观察此数据集,马上可以发现一些明显的障碍。首先,三科考试的成绩是无法比较的。由于它们的均值和标准差相去甚远,所以对它们求平均值是没有意义的。你在组合这些考试成绩之前,必须将其变换为可比较的单元。其次,为了评定等级,你需要一种方法来确定某个学生在前述得分上百分比排名。再次,表示姓名的字段只有一个,这让排序任务复杂化了。为了正确地将其排序,需要将姓和名拆开。
以上每一个任务都可以巧妙地利用R中的数值和字符处理函数完成。在讲解完下一节中的各种函数之后,我们将考虑一套可行的解决方案,以解决这项数据处理难题。
5.2 数值和字符处理函数
本节我们将综述R中作为数据处理基石的函数,它们可分为数值(数学、统计、概率)函数和字符处理函数。在阐述过每一类函数以后,我将为你展示如何将函数应用到矩阵和数据框的列(变量)和行(观测)上(参见5.2.6节)。
5.2.1 数学函数
表5-2列出了常用的数学函数和简短的用例。
对数据做变换是这些函数的一个主要用途。例如,你经常会在进一步分析之前将收入这种存在明显偏倚的变量取对数。数学函数也被用作公式中的一部分,用于绘图函数(例如x对sin(x))和在输出结果之前对数值做格式化。
表5-2中的示例将数学函数应用到了标量(单独的数值)上。当这些函数被应用于数值向量、矩阵或数据框时,它们会作用于每一个独立的值。例如,sqrt(c(4, 16, 25))的返回值为c(2, 4, 5)。
5.2.2 统计函数
常用的统计函数如表5-3所示,其中许多函数都拥有可以影响输出结果的可选参数。举例
来说:
y <- mean(x)
提供了对象x中元素的算术平均数,而:
z <- mean(x, trim = 0.05, na.rm=TRUE)
则提供了截尾平均数,即丢弃了最大5%和最小5%的数据和所有缺失值后的算术平均数。请使用help()
了解以上每个函数和其参数的用法。
要了解这些函数的实战应用,请参考代码清单5-1。这个例子演示了计算某个数值向量的均值和标准差的两种方式。
代码清单5-1 均值和标准差的计算
方法1:
x <- c(1,2,3,4,5,6,7,8)
mean(x)
sd(x)
方法2:
n <- length(x)
meanx <- sum(x)/n
css <- sum((x - meanx)^2)
sdx <- sqrt(css / (n-1))
meanx
第二种方式中修正平方和(css)的计算过程是很有启发性的:
(1) x等于c(1, 2, 3, 4, 5, 6, 7, 8),x的平均值等于4.5(length(x)返回了x中元素
的数量);
(2) (x – meanx)从x的每个元素中减去了4.5,结果为c(-3.5, -2.5, -1.5, -0.5, 0.5,
1.5, 2.5, 3.5);
(3) (x – meanx)^2将(x - meanx)的每个元素求平方,结果为c(12.25, 6.25, 2.25,
0.25, 0.25, 2.25, 6.25, 12.25);
(4) sum((x - meanx)^2)对(x - meanx)^2)的所有元素求和,结果为42。 R中公式的写法和类似MATLAB的矩阵运算语言有着许多共同之处。(我们将在附录D中具体关注解决矩阵代数问题的方法。)
5.2.3 概率函数
你可能在疑惑为何概率函数未和统计函数列在一起。(你真的对此有些困惑,对吧?)虽然根据定义,概率函数也属于统计类,但是它们非常独特,应独立设一节进行讲解。概率函数通常用来生成特征已知的模拟数据,以及在用户编写的统计函数中计算概率值。
在R中,概率函数形如 :
[dpqr]distribution_abbreviation()
其中第一个字母表示其所指分布的某一方面:
d = 密度函数(density)
p = 分布函数(distribution function)
q = 分位数函数(quantile function)
r = 生成随机数(随机偏差)
常用的概率函数列于表5-4中。
我们不妨先看看正态分布的有关函数,以了解这些函数的使用方法。如果不指定一个均值和一个标准差,则函数将假定其为标准正态分布(均值为0,标准差为1)。密度函数(dnorm)、分布函数(pnorm)、分位数函数(qnorm)和随机数生成函数(rnorm)的使用示例见表5-5。
代码清单5-2 生成服从正态分布的伪随机数
通过手动设定种子,就可以重现你的结果了。这种能力有助于我们创建会在未来取用的,以及可与他人分享的示例。
mvrnorm(n, mean, sigma)
其中n是你想要的样本大小,mean为均值向量,而sigma是方差协方差矩阵(或相关矩阵)。代码清单5-3从一个参数如下所示的三元正态分布中抽取500个观测。
代码清单5-3 生成服从多元正态分布的数据
rm(list = ls())
library(MASS