R語言里面的apply()家族簡述

我能想到的所有套路,毒液里面都有谓晌。

這個教程目的在于介紹apply()家族在R語言的用法笤妙,apply()函數(shù)算是R語言里面很基礎(chǔ)的一個函數(shù),同時還有sapply()淹父、lapply()株婴、tapply()函數(shù)精簡了apply()的用法。

apply()函數(shù)是一個很R語言的函數(shù)暑认,可以起到很好的替代冗余的for循環(huán)的作用困介,在一篇博客里面介紹過,R語言的循環(huán)操作for和while蘸际,都是基于R語言本身來實現(xiàn)的座哩,而向量操作是基于底層的C語言函數(shù)實現(xiàn)的,所以使用apply()家族進行向量計算是高性價比的粮彤。apply()可以面向數(shù)據(jù)框根穷、列表、向量等导坟,同時任何函數(shù)都可以傳遞給apply()函數(shù)屿良。

apply()函數(shù)

apply()函數(shù)的用法如下:

apply(X, MARGIN, FUN)
Here:
-x: 一個數(shù)組或者矩陣
-MARGIN: 兩種數(shù)值1或者2決定對哪一個維度進行函數(shù)計算
-MARGIN=1`: 操作基于行
-MARGIN=2`: 操作基于列
-MARGIN=c(1,2)`: 對行和列都進行操作
-FUN: 使用哪種操作,內(nèi)置的函數(shù)有mean(平均值)惫周、medium(中位數(shù))尘惧、sum(求和)、min(最小值)递递、max(最大值)喷橙,當然還包括廣大的用戶自定義函數(shù)

一個最簡單的例子就是使用apply()對一個matrix求和,以下代碼是對列求和:

> m1 <- matrix(C<-(1:10),nrow=5, ncol=6)
> m1
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    6    1    6    1    6
[2,]    2    7    2    7    2    7
[3,]    3    8    3    8    3    8
[4,]    4    9    4    9    4    9
[5,]    5   10    5   10    5   10
> a_m1 <- apply(m1, 2, sum)
> a_m1
[1] 15 40 15 40 15 40

lapply()函數(shù)

lapply()函數(shù)中多出來的l代表的是list登舞,所以lapply()和apply()的區(qū)別在于輸出的格式重慢,lapply()的輸出是一個列表(list),所以lapply()函數(shù)不需要MARGIN參數(shù):

lapply(X, FUN)
Arguments:
-X: 一個向量或者是一個對象
-FUN: 對X里面每個元素進行操作的函數(shù)

一個很簡單的示例操作就是把一個字符向量里面的字符轉(zhuǎn)成小寫:

> movies <- c("SPYDERMAN","BATMAN","VERTIGO","CHINATOWN")
> class(movies)
[1] "character"
> movies_lower <-lapply(movies, tolower)
> str(movies_lower)
List of 4
 $ : chr "spyderman"
 $ : chr "batman"
 $ : chr "vertigo"
 $ : chr "chinatown"

我們可以看到逊躁,輸出的內(nèi)容是以list形式給出的似踱,為了方便,我們可以使用unlist()函數(shù)進行整合:

> movies_lower <-unlist(lapply(movies,tolower))
> str(movies_lower)
 chr [1:4] "spyderman" "batman" "vertigo" "chinatown"

sapply()函數(shù)

sapply()函數(shù)做的事情和lapply()一樣,可以理解為是一個簡化的lapply核芽,返回的是一個向量(vector)使得對解讀更加友好囚戚,其使用方法和lapply一樣,不過多了兩個參數(shù): simplify&use.NAMEs,simplify = T可以將輸出結(jié)果數(shù)組化轧简,如果設置為false驰坊,sapply()函數(shù)就和lapply()函數(shù)沒有差別了,use.NAMEs = T可以設置字符串為字符名哮独。

> dt <- cars
> lmn_cars <- lapply(dt, min)
> smn_cars <- sapply(dt, min)
> smn_cars_sim <- sapply(dt, min, simplify = F)
> lmn_cars
$`speed`
[1] 4

$dist
[1] 2

> smn_cars
speed  dist 
    4     2 
> smn_cars_sim
$`speed`
[1] 4

$dist
[1] 2

> class(lmn_cars)
[1] "list"
> class(smn_cars)
[1] "numeric"
> class(smn_cars_sim)
[1] "list"

那我們就稍微總結(jié)一下這三個函數(shù)的區(qū)別:

Function Second Header 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

tapply()函數(shù)

這里拓展一個函數(shù):tapply()拳芙,它可以對一個向量里面進行分組統(tǒng)計操作。

是不是想起了dplyr包里面的group_by函數(shù) + summarize()函數(shù)皮璧。

其參數(shù)為:

tapply(X, INDEX, FUN = NULL)
Arguments:
-X: 一個對象舟扎,一般都是向量
-INDEX: 一個包含分類因子的列表(list)
-FUN: 對X里面每個元素進行操作的函數(shù)

數(shù)據(jù)分析的一部分工作就是分組進行統(tǒng)計,舉例來說悴务,根據(jù)一個特性來對一個群體進行分組計算平均值睹限。拿鳶尾花數(shù)據(jù)(iris)舉例,其有三個品種:Setosa, Versicolor, Virginica讯檐,以下代碼可以計算三個品種平均寬度:

> data(iris)
> 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
> tapply(iris$Sepal.Width, iris$Species, median)
    setosa versicolor  virginica 
       3.4        2.8        3.0 

使用我之前說的dplyr包可以實現(xiàn)同樣的目的:

> iris %>% group_by(Species) %>%
+   summarise(mean(Sepal.Width))
# A tibble: 3 x 2
  Species    `mean(Sepal.Width)`
  <fct>                    <dbl>
1 setosa                    3.43
2 versicolor                2.77
3 virginica                 2.97

Conclusion

其實apply()家族還有多個衍生函數(shù)羡疗,包括vapply、mapply别洪、rapply等叨恨,但是具體應用其實并不很常用,摒棄了for循環(huán)和while循環(huán)挖垛,我們還是有很多方法可以高效而簡潔得實現(xiàn)我們的目的得特碳。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晕换,隨后出現(xiàn)的幾起案子午乓,更是在濱河造成了極大的恐慌,老刑警劉巖闸准,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件益愈,死亡現(xiàn)場離奇詭異,居然都是意外死亡夷家,警方通過查閱死者的電腦和手機蒸其,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來库快,“玉大人摸袁,你說我怎么就攤上這事∫迤粒” “怎么了靠汁?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵蜂大,是天一觀的道長。 經(jīng)常有香客問我蝶怔,道長奶浦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任踢星,我火速辦了婚禮澳叉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沐悦。我一直安慰自己成洗,他們只是感情好,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布藏否。 她就那樣靜靜地躺著瓶殃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秕岛。 梳的紋絲不亂的頭發(fā)上碌燕,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天误证,我揣著相機與錄音继薛,去河邊找鬼。 笑死愈捅,一個胖子當著我的面吹牛遏考,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蓝谨,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼灌具,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了譬巫?” 一聲冷哼從身側(cè)響起咖楣,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎芦昔,沒想到半個月后诱贿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡咕缎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年珠十,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凭豪。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡焙蹭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嫂伞,到底是詐尸還是另有隱情孔厉,我是刑警寧澤拯钻,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站烟馅,受9級特大地震影響说庭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜郑趁,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一刊驴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寡润,春花似錦捆憎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至变抽,卻和暖如春础拨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绍载。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工诡宗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人击儡。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓塔沃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阳谍。 傳聞我的和親對象是個殘疾皇子蛀柴,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容

  • R語言中的以apply()函數(shù)為首的apply()家族,提供了強大而方便的循環(huán)功能矫夯,這些函數(shù)說起來簡單鸽疾,用起來可能...
    大數(shù)據(jù)技術(shù)派閱讀 1,327評論 0 1
  • 循環(huán)對于代碼運行來說是非常消耗時間和資源的,在R中训貌,要盡量少使用for while循環(huán)制肮,用apply函數(shù)族的話對于...
    willnight閱讀 3,464評論 0 2
  • 生物考完歸來,只剩生物統(tǒng)計學待我手刃了旺订。轉(zhuǎn)眼著手于熟悉的環(huán)境弄企,想想學習R也有幾個月的時光了。談得上入手区拳,談不上熟練...
    王詩翔閱讀 16,390評論 9 65
  • 這次一起去香港拘领,讓我明白了。 人不需要活得太認真了…… 有哪份閑情去計較什么樱调, 還不如把精力多花點在自己的身上约素。届良。...
    桔梗花蕾閱讀 72評論 0 0
  • 一個人圣猎,呆在宿舍士葫,嗅不到中秋的味道。 只是送悔,在跟媽媽的聊天中慢显,感覺到了沒有回家過節(jié)的失落和心酸。 昨晚欠啤,徹夜難眠荚藻。...
    減肥的女孩閱讀 287評論 0 1