本教程旨在介紹apply()函數(shù)集合。apply()函數(shù)是所有集合中最基本的。我們還將學(xué)習(xí)sapply(),lapply()和tapply()。apply集合可以看作是循環(huán)的替代品。
如果將R與Anaconda一起安裝,則apply()集合與R基本軟件包捆綁在一起。apply()函數(shù)可以提供許多函數(shù),以對對象(數(shù)據(jù)框,列表,向量等)的集合執(zhí)行冗余應(yīng)用程序。apply()的目的主要是為了避免顯式使用循環(huán)結(jié)構(gòu)。它們可用于輸入列表,矩陣或數(shù)組并應(yīng)用函數(shù)。任何函數(shù)都可以傳遞到apply()中。
在本教程中,您將學(xué)習(xí):
- apply()函數(shù)
- lapply()函數(shù)
- sapply()函數(shù)
- 切片矢量
- tapply()函數(shù)
apply()函數(shù)
apply()將數(shù)據(jù)框或矩陣作為輸入,并以矢量,列表或數(shù)組形式輸出。apply()函數(shù)主要用于避免重復(fù)使用循環(huán)結(jié)構(gòu)。它是所有可以在矩陣上使用的最基本的集合。
此函數(shù)接受3個(gè)參數(shù):
apply(X, MARGIN, FUN)
-x:數(shù)組或矩陣
-MARGIN:取一個(gè)介于1到2之間的值或范圍,以定義該函數(shù)的應(yīng)用位置:
-MARGIN = 1`:對行執(zhí)行操作
-MARGIN = 2`:對列執(zhí)行操作
-MARGIN = c(1,2)`該操作在行和列上執(zhí)行
-FUN:告訴應(yīng)用哪個(gè)功能??梢詰?yīng)用平均值,中位數(shù),和,最小值,最大值甚至用戶定義的函數(shù)等內(nèi)置函數(shù)
最簡單的示例是對所有列求和。代碼apply(m1,2,sum)將sum函數(shù)應(yīng)用于矩陣5x6,并返回?cái)?shù)據(jù)集中可訪問的每一列的總和。
m1 <- matrix(C<-(1:10),nrow=5, ncol=6)
m1
a_m1 <- apply(m1, 2, sum)
a_m1
輸出:
最佳實(shí)踐:在將值打印到控制臺之前,先存儲它們。
lapply()函數(shù)
lapply()函數(shù)可用于對列表對象執(zhí)行操作,并返回與原始集合長度相同的列表對象。lappy()返回一個(gè)長度與輸入列表對象相似的列表,其每個(gè)元素都是將FUN應(yīng)用于列表的相應(yīng)元素的結(jié)果。lapply()將列表,向量或數(shù)據(jù)框作為輸入,并在列表中給出輸出。
lapply(X, FUN)
Arguments:
-X: A vector or an object
-FUN: Function applied to each element of x
lapply()中的l代表列表。lapply()和apply()之間的區(qū)別在于輸出返回之間。lapply()的輸出是一個(gè)列表。lapply()可以用于其他對象,例如數(shù)據(jù)框和列表。
lapply()函數(shù)不需要MARGIN。
一個(gè)非常簡單的示例是使用tolower函數(shù)將矩陣的字符串值更改為小寫。我們用著名電影的名稱構(gòu)造一個(gè)矩陣。名稱為大寫形式。
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()將列表轉(zhuǎn)換為向量。
films_lower <- unlist(lapply(movies,tolower))
str(movies_lower)
輸出:
## chr [1:4] "spyderman" "batman" "vertigo" "chinatown"
sapply()函數(shù)
sapply()函數(shù)將列表,向量或數(shù)據(jù)幀作為輸入,并以向量或矩陣形式輸出。它對列表對象的操作很有用,并返回與原始集合長度相同的列表對象。sapply()函數(shù)執(zhí)行的功能與lapply()函數(shù)相同,但返回一個(gè)向量。
sapply(X, FUN)
Arguments:
-X: A vector or an object
-FUN: Function applied to each element of x
我們可以從汽車數(shù)據(jù)集中測量汽車的最小速度和停車距離。
dt <- cars
lmn_cars <- lapply(dt, min)
smn_cars <- sapply(dt, min)
lmn_cars
smn_cars
輸出:
## $speed
## [1] 4
## $ dist
## [1] 2
## speed dist
## 4 2
我們可以在lapply()或sapply()中使用用戶內(nèi)置函數(shù)。我們創(chuàng)建一個(gè)名為avg的函數(shù)來計(jì)算向量最小值和最大值的平均值。
avg <- function(x) {
( min(x) + max(x) ) / 2}
fcars <- sapply(dt, avg)
fcars
輸出量
## speed dist
## 14.5 61.0
sapply()函數(shù)在返回的輸出中比lapply()更有效,因?yàn)閟apply()將值直接存儲到向量中。在下一個(gè)示例中,我們將看到情況并非總是如此。
下表總結(jié)了apply(),sapply()和lapply()之間的區(qū)別:
| Function | Arguments | Objective | Input | Output |
|---|---|---|---|---|
| apply | apply(x, MARGIN, FUN) | Apply a function to the rows or columns or both | Data frame or matrix | vector, list, array |
| lapply | lapply(X, FUN) | Apply a function to all the elements of the input | List, vector or data frame | list |
| sapply | sappy(X FUN) | Apply a function to all the elements of the input | List, vector or data frame | vector or matrix |
切片矢量
我們可以使用lapply()或sapply()互換來切片數(shù)據(jù)框。我們創(chuàng)建一個(gè)函數(shù)below_average(),該函數(shù)接受數(shù)值的向量,并返回僅包含嚴(yán)格高于平均值的值的向量。我們將兩個(gè)結(jié)果與 identical() 函數(shù)進(jìn)行比較。
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()函數(shù)
tapply()計(jì)算向量中每個(gè)因子變量的度量(均值,中位數(shù),最小值,最大值等)或函數(shù)。這是一項(xiàng)非常有用的功能,可讓您創(chuàng)建向量的子集,然后將某些功能應(yīng)用于每個(gè)子集。
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
數(shù)據(jù)科學(xué)家或研究人員的部分工作是計(jì)算變量匯總。例如,根據(jù)特征測量平均值或組數(shù)據(jù)。大多數(shù)數(shù)據(jù)按ID,城市,國家/地區(qū)等分組??偨Y(jié)小組會發(fā)現(xiàn)更多有趣的模式。
為了了解其工作原理,讓我們使用虹膜數(shù)據(jù)集。該數(shù)據(jù)集在機(jī)器學(xué)習(xí)領(lǐng)域非常有名。該數(shù)據(jù)集的目的是預(yù)測三種花類中的每一種的類別:萼片,雜色和維珍妮卡。數(shù)據(jù)集收集每個(gè)物種的長度和寬度信息。
作為先前的工作,我們可以計(jì)算每個(gè)物種的長度的中位數(shù)。tapply()是執(zhí)行此計(jì)算的快速方法。
data(iris)
tapply(iris$Sepal.Width, iris$Species, median)
輸出:
## setosa versicolor virginica
## 3.4 2.8 3.0
