R apply()、lapply()、sapply()、tapply() 及其示例
本教程旨在介绍apply()函数集合。apply()函数是所有集合中最基础的。我们还将学习sapply()、lapply()和tapply()。apply集合可以被看作是循环的替代品。
如果您使用Anaconda安装R,apply()集合将与r essential包捆绑在一起。R中的apply函数可以接收多个函数,对对象集合(数据框、列表、向量等)执行冗余应用。apply()的目的主要是避免显式使用循环结构。它们可以用于输入列表、矩阵或数组,并应用一个函数。任何函数都可以传递给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) 将对 5x6 矩阵应用 sum 函数,并返回数据集中可访问的每一列的总和。
m1 <- matrix(C<-(1:10),nrow=5, ncol=6) m1 a_m1 <- apply(m1, 2, sum) a_m1
输出
最佳实践:在将值打印到控制台之前先存储它们。
lapply() 函数
lapply() 函数对于对列表对象执行操作非常有用,并返回与原始集合长度相同的列表对象。lappy() 返回一个与输入列表对象长度相似的列表,其中每个元素都是将 FUN 应用于列表相应元素的结果。Lapply in R 以列表、向量或数据框为输入,并以列表为输出。
lapply(X, FUN) Arguments: -X: A vector or an object -FUN: Function applied to each element of x
lapply() 中的 l 代表 list。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() 函数以列表、向量或数据框为输入,并以向量或矩阵为输出。它对于对列表对象执行操作非常有用,并返回与原始集合长度相同的列表对象。Sapply function in R 的作用与 lapply() 函数相同,但返回的是一个向量。
sapply(X, FUN) Arguments: -X: A vector or an object -FUN: Function applied to each element of x
我们可以从 cars 数据集中测量汽车的最小速度和刹车距离。
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
Sapply in R 比 lapply() 在返回的输出方面更有效率,因为 sapply() 直接将值存储到向量中。在下一个示例中,我们将看到情况并非总是如此。
我们可以在下表中总结 apply()、sapply() 和 lapply() 之间的区别
函数 | 参数 | 目标 | 输入 | 输出 |
---|---|---|---|---|
apply | apply(x, MARGIN, FUN) | 将函数应用于行、列或两者 | 数据框或矩阵 | 向量、列表、数组 |
lapply | lapply(X, FUN) | 将函数应用于输入的所有元素 | 列表、向量或数据框 | 列表 |
sapply | sapply(X, FUN) | 将函数应用于输入的所有元素 | 列表、向量或数据框 | 向量或矩阵 |
切片向量
我们可以互换使用 lapply() 或 sapply() 来切片数据框。我们创建一个名为 below_average() 的函数,该函数接受一个数值向量,并返回一个仅包含严格高于平均值的向量。我们使用 identical() 函数比较两个结果。
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、城市、国家等分组。按组汇总会揭示更有趣的模式。
为了理解它是如何工作的,让我们使用 iris 数据集。这个数据集在机器学习界非常有名。此数据集的目的是预测三个花卉物种:萼片、变色萼片、弗吉尼亚花的类别。该数据集收集了每个物种的长度和宽度信息。
作为先前的工作,我们可以计算每个物种长度的中位数。R 中的 Tapply 是执行此计算的快速方法。
data(iris) tapply(iris$Sepal.Width, iris$Species, median)
输出
## setosa versicolor virginica ## 3.4 2.8 3.0