R語言中的循環函數(Grouping Function)

R語言中有幾個經常使用的函數,能夠按組對數據進行處理,apply, lapply, sapply, tapply, mapply,等。這幾個函數功能有些相似,下面介紹下這幾個函數的用法。app

Apply

這是對一個Matrix或者Array進行某個維度的運算。其格式是:函數

Apply(數據,維度Index,運算函數,函數的參數)字符串

對於Matrix來講,其維度值爲2,第二個參數維度Index中,1表示按行運算,2表示按列運算。下面舉一個例子:io

m<-matrix(1:6,2,3)function

構建一個簡單的2行3列的矩陣,內容爲:class

     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
若是咱們要計算每一行的sum值,那麼咱們能夠寫爲:
apply(m,1,sum)
[1]  9 12
若是要計算每一列的mean值,那麼改成:
apply(m,2,mean)
[1] 1.5 3.5 5.5
假如某個值爲NA,那麼要忽略NA值,進行每一行的SUM怎麼辦呢?
m[2,2]<-NA
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2   NA    6
apply(m,1,sum)
[1]  9 NA
自己sum函數有一個參數na.rm,咱們能夠將這個參數帶人到apply函數中,做爲第4個參數:
apply(m,1,sum,na.rm=TRUE)
[1] 9 8
須要注意的是若是是Data Frame,那麼系統會將其轉爲Matrix,若是全部Column不是數字類型或者類型不一致,致使轉換失敗,那麼apply是運算不出任何一列的結果的。

Lapply

前面說到apply是對於matrix和array的,針對list,咱們可使用lapply函數。該函數接收list,返回的結果也是一個list。其調用以下:
Apply(數據,運算函數,函數的參數)
對於Data Frame來講,若是不一樣的列有不一樣的數據類型,不能轉換成Matrix,可是卻能夠轉換成List,而後使用lapply函數。
咱們創建一個學生名字,年齡和成績的Data Frame,而後統計平均年齡和平均成績,因爲name列不是數值類型,因此沒法算平均值,因此咱們能夠對非數值的數據只取count數量。這裏就須要用到自定義函數。
函數能夠是匿名函數,也能夠是以前定義好的函數,因爲這裏邏輯簡單,咱們能夠用匿名函數解決。

s<-data.frame(name=c("Devin","Edward","Lulu"),age=c(30,33,29),score=c(95,99,90))匿名函數

    name age score
1  Devin  30    95
2 Edward  33    99
3   Lulu  29    90


lapply(s,function(x){if(is.numeric(x)){mean(x)}else{length(x)}})List

$name
[1] 3

$age
[1] 30.66667

$score
[1] 94.66667
咱們能夠看到返回了一個List的結果,裏面包含3個項,每一個項是函數執行的結果。lapply返回的結果和傳入的List的結構相同,傳入多少個Item,返回的也是多少個Item。

Sapply

Sapply函數和Lapply函數很相似,也是對List進行處理,只是在返回結果上,Sapply會根據結果的數據類型和結構,從新構建一個合理的數據類型返回。調用格式以下:
Apply(數據,運算函數,函數的參數,simplify = TRUE, USE.NAMES = TRUE)
對於其中的simplify參數,就是指明是否對返回的結果集從新組織,若是爲FALSE,那麼就至關於lapply了。USE.NAMES是對字符串數據處理時,是否使用字符串做爲命名的。
仍是上面的例子,只是把lapply換成sapply:
sapply(s,function(x){if(is.numeric(x)){mean(x)}else{length(x)}})
    name      age    score 
 3.00000 30.66667 94.66667 
咱們能夠看到結果集變成了一個數字向量,而不是List了。

Mapply

這是對多個數據(multivariate)進行sapply處理,只是調用是參數位置有所變化,先把函數放前面:
mapply(運算函數,函數的參數,第一個傳入參數,第二個數據…,SIMPLIFY = TRUE,USE.NAMES = TRUE)
好比咱們自定義一個函數m3,接受3個數值參數,而後將3個數字相乘返回結果:
m3<-function(a,b,c){a*b*c}
而後咱們構建3個向量,他們具備相同的長度:

a<-1:5
b<-2:6
c<-5:1map

如今咱們要求a,b,c中的對應各位數進行m3函數的運算,也就是把a,b,c的第一個數作運算,而後把a,b,c的第二個數作運算,而後第三個數~~~這時候就用mapply很方便:數據類型

mapply(m3,a,b,c)
[1] 10 24 36 40 30

OK,就這麼簡單,實現了對應的各位元素的運算。

Tapply

前面介紹的幾個apply函數都是對總體數據進行處理,而tapply是對向量中的數據進行分組處理。先看看tapply函數的調用格式:
tapply(向量數據,分組標識,運算函數,函數的參數,simplify = TRUE)
咱們以一個學生數據的Data Frame爲例來說解tapply函數,先構建一個新的學生數據,包含name,age,score,class,gender:

s<-data.frame(name=c("Devin","Edward","Lulu","Jeneen"),age=c(30,33,29,32),score=c(95,99,90,88),class=c(1,2,1,2),gender=c("M","M","F","F"))

    name age score class gender
1  Devin  30    95     1      M
2 Edward  33    99     2      M
3   Lulu  29    90     1      F
4 Jeneen  32    88     2      F

若是咱們要計算每一個班的平均成績,那麼使用tapply的方法是:

tapply(s$score,s$class,mean)
   1    2 
92.5 93.5 
若是改成按gender算平均成績,那麼就是:
tapply(s$score,s$gender,mean)
 F  M 
89 97 
若是同時按class和gender來看呢?這裏就須要把兩個向量構建成list做爲第二個參數傳入:
tapply(s$score,list(s$class,s$gender),mean)
   F  M
1 90 95
2 88 99
相關文章
相關標籤/搜索