R 函数 apply()、lapply()、sapply()、tapply() 及其示例

本教程旨在介绍apply()函数集合。apply()函数是所有集合中最基本的函数。我们还将学习sapply()、lapply()和tapply()。apply集合可以看作是循环的替代品。

apply() 集合与 必不可少 如果你 使用 Anaconda 安装 R。R 函数中的 apply 可以输入许多函数,以对对象集合(数据框、列表、向量等)执行冗余应用。apply() 的目的主要是避免显式使用循环构造。它们可用于输入列表、矩阵或数组并应用函数。任何函数都可以传递到 apply() 中。

apply() 函数

应用() 将数据框或矩阵作为输入,并以向量、列表或数组形式输出。应用 R 中的函数 主要用于避免显式使用循环结构。它是矩阵上可以使用的所有集合中最基本的集合。

此函数接受 3 个参数:

apply(X, MARGIN, FUN)
Here:
-x: an array or matrix
-MARGIN:  take a value or range between 1 and 2 to define where to apply the function:
-MARGIN=1`: the manipulation is performed on rows
-MARGIN=2`: the manipulation is performed on columns
-MARGIN=c(1,2)` the manipulation is performed on rows and columns
-FUN: tells which function to apply. Built functions like mean, median, sum, min, max and even user-defined functions can be applied>

最简单的例子是对矩阵的所有列求和。代码apply(m1, 2, sum)将对5×6矩阵应用sum函数,并返回数据集中可访问的每一列的和。

m1 <- matrix(C<-(1:10),nrow=5, ncol=6)
m1
a_m1 <- apply(m1, 2, sum)
a_m1

输出:

R 中的 Apply() 函数示例
R 中的 apply() 函数示例

最佳实践:在将值打印到控制台之前存储该值。

lapply() 函数

lapply() 函数可用于对列表对象执行操作并返回与原始集长度相同的列表对象。lappy() 返回与输入列表对象长度相似的列表,其中每个元素都是将 FUN 应用于列表相应元素的结果。R 中的 Lapply 将列表、向量或数据框作为输入并以列表形式输出。

lapply(X, FUN)
Arguments:
-X: A vector or an object
-FUN: Function applied to each element of x	

lapply() 中的 l 代表列表。lapply() 和 apply() 之间的区别在于输出返回。lapply() 的输出是一个列表。lapply() 可用于其他对象,如数据框和列表。

lapply() 函数不需要 MARGIN。

一个非常简单的例子是使用 tolower 函数将矩阵的字符串值更改为小写。我们用著名电影的名称构建一个矩阵。名称采用大写格式。

movies <- c("SPYDERMAN","BATMAN","VERTIGO","CHINATOWN")
movies_lower <-lapply(movies, tolower)
str(movies_lower)

输出:

## List of 4
## $:chr"spyderman"
## $:chr"batman"
## $:chr"vertigo"
## $:chr"chinatown"

我们可以使用 unlist() 将列表转换为向量。

movies_lower <-unlist(lapply(movies,tolower))
str(movies_lower)

输出:

##  chr [1:4] "spyderman" "batman" "vertigo" "chinatown"

sapply() 函数

sapply() 函数以列表,向量或数据框作为输入并以向量或 矩阵。它对于列表对象的操作很有用,并返回与原始集长度相同的列表对象。R 中的 Sapply 函数与 lapply() 函数执行相同的工作,但返回一个向量。

sapply(X, FUN)
Arguments:
-X: A vector or an object
-FUN: Function applied to each element of x

我们可以从汽车数据集中测量汽车的最低速度和停车距离。

dt <- cars
lmn_cars <- lapply(dt, min)
smn_cars <- sapply(dt, min)
lmn_cars

输出:

## $speed
## [1] 4
## $dist
## [1] 2
smn_cars

输出:

## speed  dist 
##     4     2
lmxcars <- lapply(dt, max)
smxcars <- sapply(dt, max)
lmxcars

输出:

## $speed
## [1] 25
## $dist
## [1] 120
smxcars

输出:

## speed  dist 
##    25   120

我们可以将用户内置函数用于 lapply() 或 sapply()。我们创建一个名为 avg 的函数来计算向量的最小值和最大值的平均值。

avg <- function(x) {  
  ( min(x) + max(x) ) / 2}
fcars <- sapply(dt, avg)
fcars

输出

## speed  dist
##  14.5  61.0

R 中的 Sapply 在返回的输出中比 lapply() 更高效,因为 sapply() 将值直接存储到向量中。在下一个示例中,我们将看到情况并非总是如此。

我们可以在下表中总结apply()、sapply()和`lapply()之间的区别:

功能 参数 目的 输入 输出
应用 应用(x,MARGIN,FUN) 将函数应用于行或列或两者 数据框或矩阵 向量、列表、数组
拉普利 lapply(X,FUN) 将函数应用于输入的所有元素 列表、向量或数据框 名单
萨普利 sapply(X,FUN) 将函数应用于输入的所有元素 列表、向量或数据框 向量或矩阵

切片矢量

我们可以交替使用 lapply() 或 sapply() 来对数据框进行切片。我们创建一个函数 below_average(),它接受一个数值向量并返回一个仅包含严格高于平均值的值的向量。我们将两个结果与 same() 函数进行比较。

below_ave <- function(x) {  
    ave <- mean(x) 
    return(x[x > ave])
}
dt_s<- sapply(dt, below_ave)
dt_l<- lapply(dt, below_ave)
identical(dt_s, dt_l)

输出:

## [1] TRUE

tapply() 函数

tapply() 计算向量中每个因子变量的度量(平均值、中位数、最小值、最大值等)或函数。这是一个非常有用的函数,它允许您创建向量的子集,然后将一些函数应用于每个子集。

tapply(X, INDEX, FUN = NULL)
Arguments:
-X: An object, usually a vector
-INDEX: A list containing factor
-FUN: Function applied to each element of x

数据科学家或研究人员的部分工作是计算变量的摘要。例如,根据特征测量平均值或分组数据。大多数数据按 ID、城市、国家/地区等分组。对组进行汇总可以揭示更多有趣的模式。

为了了解其工作原理,让我们使用鸢尾花数据集。这个数据集在机器学习领域非常有名。该数据集的目的是预测三种花卉的类别:萼片花、杂色花、维吉尼亚花。该数据集收集了每种花卉的长度和宽度信息。

作为一项先决工作,我们可以计算每个物种的长度中位数。R 中的 Tapply 是一种快速执行此计算的方法。

data(iris)
tapply(iris$Sepal.Width, iris$Species, median)

输出:

##     setosa versicolor  virginica 
##        3.4        2.8        3.0