使用匿名函数和 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 有一些内置函数,更适合计算列和行和,意思是: colMeansrowMeans

现在,让我们做一个不同的,更有意义的任务:让我们计算那些大于 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 系列函数更具可预测性(参见备注)。