R四大高效編程神器——apply家族

本節(jié)提要:

  • apply()函數(shù)
  • sapply()函數(shù)
  • lapply()函數(shù)
  • tapply()函數(shù)

熟悉R編程的人都知道R語言的apply家族,而R語言入門容易,簡單學一學就能寫出一些代碼伦意,而良好的編程習慣和優(yōu)雅的代碼風格卻是一個長期潛移默化火窒、逐步積累的過程硼补。

R語言的apply家族正是為你高效編程提供了可能性,其令人驚訝的處理方式可能會成為你選擇它們的理由熏矿。

apply()

要點:
  • 作用對象:數(shù)據(jù)框(dataframe)或 矩陣(matrix)已骇;
  • 輸出:一個向量离钝;
  • 關鍵參數(shù):MARGINFUN

apply()函數(shù)能夠快速幫助你對數(shù)據(jù)框或矩陣按行(MARGIN = 1)或列(MARGIN = 2)的方式來進行處理褪储,而這個處理正是由FUN所定義的卵渴。

示例:
#a matrix
mtx <- matrix(1:9, byrow = T, nrow = 3)
mtx
#     [,1] [,2] [,3]
#[1,]    1    2    3
#[2,]    4    5    6
#[3,]    7    8    9
apply(X = mtx, 
      MARGIN = 1, #by row
      FUN = mean) #cal mean value (mean function)
#[1] 2 5 8

這段代碼實現(xiàn)了對該矩陣按行取均值的操作,最后返回一個向量鲤竹,分別對應每一行的均值浪读,當然你也可以自定義函數(shù),例如還是上面的目的辛藻,用自己寫的函數(shù)來實現(xiàn)(當然這完全沒必要):

apply(X = mtx, 
      MARGIN = 1, #by row
      FUN = function(x){
        sum(x)/length(x)
      }) #cal mean value (custome function)

想給大家分享的是碘橘,這段代碼里面的x到底是個什么?答案是 向量吱肌。也就是說 apply()函數(shù)講數(shù)據(jù)框或矩陣給你拆成了一個個向量供你進行操作痘拆,我們來簡單驗證一下:

apply(X = mtx, 
      MARGIN = 1, #by row
      FUN = function(x){
        is.vector(x)
      })
#[1] TRUE TRUE TRUE

sapply()

要點:
  • 作用對象:數(shù)據(jù)框(dataframe),向量(vector)或 列表(list)氮墨;
  • 輸出:向量(vector)或 矩陣(matrix)纺蛆;
  • 關鍵參數(shù):FUN

從本質上看规揪,R語言的數(shù)據(jù)框是一種特殊的列表(每個組件長度都相等的列表)桥氏。這個組件就是數(shù)據(jù)框的每一列,由于數(shù)據(jù)框的特點猛铅,這些組件的類型是不一樣的识颊,有的是字符型向量,有的是數(shù)值型向量等等奕坟。

首先來看sapply()函數(shù)是如何處理列表的:

#a list
list <- list(a = sample(1:10, 5),
             b = 1:5)
list
#$a
#[1] 4 6 8 1 5
#$b
#[1] 1 2 3 4 5
sapply(list, FUN = sum)
# a  b 
#24 15 

最終是對列表的每個組件進行了函數(shù)(sum())的操作祥款,返回了一個向量。

基于前面對數(shù)據(jù)框和列表之間聯(lián)系的認識月杉,我們很自然的就可以知道刃跛,如果將sapply()函數(shù)作用到數(shù)據(jù)框上會發(fā)生什么:對數(shù)據(jù)框的每一列進行相應的操作:

#a dataframe
dataframe <- data.frame(a = sample(1:10, 5),
                        b = 1:5)
dataframe
#   a b
#1  2 1
#2  9 2
#3 10 3
#4  5 4
#5  6 5
sapply(dataframe, FUN = sum)
# a  b 
#32 15 

果然是對數(shù)據(jù)框的每一列進行了求和。

lapply()

要點:
  • 作用對象:數(shù)據(jù)框(dataframe)苛萎,向量(vector)或 列表(list)桨昙;
  • 輸出:列表(list);
  • 關鍵參數(shù):FUN腌歉。

lapply()sapply()函數(shù)很像蛙酪,不同點在于前者的輸出是列表,這在很多時候會給我們帶來一些意想不到的便利翘盖。暫時只做一個簡單的使用示例:

list <- list(a = sample(1:10, 5),
             b = 1:5)
list
lapply(list, FUN = sum)
#$a
#[1] 38
#$b
#[1] 15

tapply()

要點:
  • 作用對象:向量(vector)桂塞;
  • 輸出:向量(vector);
  • 關鍵參數(shù):INDEX馍驯,FUN阁危。

tapply()函數(shù)在進行分組統(tǒng)計時具有非常大的作用玛痊,簡單理解來說,tapply()函數(shù)就是對向量X按照因子INDEX進行函數(shù)FUN的操作狂打。這里我們以鳶尾花內置數(shù)據(jù)集為例來看看:

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
#calculate mean Sepal length for each species
tapply(iris$Sepal.Length, 
       INDEX = factor(iris$Species), #group by species
       FUN = mean) #calculate mean value
#    setosa versicolor  virginica 
#     5.006      5.936      6.588

這實際上和dplyrgroup_by()很像擂煞,也就是說這個功能還可以用這段代碼實現(xiàn):

library(dplyr)
iris %>% 
  group_by(Species) %>% 
  summarise(mean = mean(Sepal.Length))

不過返回的是數(shù)據(jù)框罷了。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末趴乡,一起剝皮案震驚了整個濱河市对省,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌晾捏,老刑警劉巖官辽,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異粟瞬,居然都是意外死亡同仆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門裙品,熙熙樓的掌柜王于貴愁眉苦臉地迎上來俗批,“玉大人,你說我怎么就攤上這事市怎∷晖” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵区匠,是天一觀的道長干像。 經(jīng)常有香客問我,道長驰弄,這世上最難降的妖魔是什么麻汰? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮戚篙,結果婚禮上五鲫,老公的妹妹穿的比我還像新娘。我一直安慰自己岔擂,他們只是感情好位喂,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著乱灵,像睡著了一般塑崖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上痛倚,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天规婆,我揣著相機與錄音,去河邊找鬼。 笑死聋呢,一個胖子當著我的面吹牛苗踪,可吹牛的內容都是我干的颠区。 我是一名探鬼主播削锰,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼毕莱!你這毒婦竟也來了器贩?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤朋截,失蹤者是張志新(化名)和其女友劉穎蛹稍,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體部服,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡唆姐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了廓八。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奉芦。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖剧蹂,靈堂內的尸體忽然破棺而出声功,到底是詐尸還是另有隱情,我是刑警寧澤宠叼,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布先巴,位于F島的核電站,受9級特大地震影響冒冬,放射性物質發(fā)生泄漏伸蚯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一简烤、第九天 我趴在偏房一處隱蔽的房頂上張望朝卒。 院中可真熱鬧,春花似錦乐埠、人聲如沸抗斤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瑞眼。三九已至,卻和暖如春棵逊,著一層夾襖步出監(jiān)牢的瞬間伤疙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留徒像,地道東北人黍特。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像锯蛀,于是被迫代替她去往敵國和親灭衷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內容