apply 用于在数组或矩阵的边界上评估函数(可能是匿名函数)。
让我们使用iris数据集来说明这个想法。该iris数据集具有来自3个物种的150种花朵的测量值。让我们看看该数据集的结构:
> head(iris) Sepal.LengthSepal.WidthPetal.LengthPetal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa
现在,假设您想知道每个变量的平均值。解决此问题的一种方法可能是使用for循环,但是R程序员通常会更喜欢使用apply(出于某些原因,请参见备注):
> apply(iris[1:4], 2, mean) Sepal.Length Sepal.WidthPetal.Length Petal.Width 5.843333 3.057333 3.758000 1.199333
在第一个参数中,我们子集iris只包括前4列,因为它mean仅适用于数字数据。
第二个参数值2表示我们只想在列上工作(r×c数组的第二个下标);1会给行的意思。
同样,我们可以计算出更有意义的值:
# standard deviation apply(iris[1:4], 2, sd) # variance apply(iris[1:4], 2, var)
警告:R具有一些内置函数,这些函数更适合于计算列和行之和以及均值:colMeans和rowMeans。
现在,让我们做另外一个更有意义的任务:让我们只计算那些大于的值的均值0.5。为此,我们将创建自己的mean功能。
> our.mean.function <- function(x) { mean(x[x > 0.5]) } > apply(iris[1:4], 2, our.mean.function) Sepal.Length Sepal.WidthPetal.Length Petal.Width 5.843333 3.057333 3.758000 1.665347
(请注意的均值之差Petal.Width)
但是,如果我们不想在其余的代码中使用此功能呢?然后,我们可以使用匿名函数,并编写如下代码:
apply(iris[1:4], 2, function(x) { mean(x[x > 0.5]) })
因此,正如我们所看到的,我们可以仅使用apply一行就对数据集的列或行执行相同的操作。
注意:由于apply根据指定函数结果的长度返回的输出类型非常不同,因此在您不进行交互式工作的情况下,它可能不是最佳选择。其他一些*apply家庭功能更具可预测性(请参见备注)。