使用匿名函数和 apply
apply
用于评估数组或矩阵边缘的函数(可能是匿名函数)。
让我们使用 iris
数据集来说明这个想法。iris
数据集测量了来自 3 个物种的 150 朵花。让我们看看这个数据集的结构:
> head(iris)
Sepal.Length Sepal.Width Petal.Length Petal.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.Width Petal.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.Width Petal.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
系列函数更具可预测性(参见备注)。