(四)控制流游添、函數(shù)與apply家族

控制流

R語言的循環(huán)和控制流包括:if、else通熄、 next唆涝、while、for等語句唇辨。
R語句的縮進(jìn)多用大括號廊酣,如for循環(huán)后面的操作需放在大括號里面;一般來說if條件后面的操作可以不用大括號括起來赏枚, 但是當(dāng)使用if-else結(jié)構(gòu)時必須使用大括號將操作括起來亡驰。next的作用類似于Python中的continue晓猛,表示跳過。while表示重復(fù)操作凡辱,循環(huán)內(nèi)部一般需要一個break來跳出循環(huán)鞍帝。此外,while煞茫、forif后面的條件語句都需要用小括號括起來摄凡。
R中函數(shù)直接使用<-進(jìn)行賦值給一個變量续徽,函數(shù)使用return()返回值,若不使用return語句亲澡,默認(rèn)把最后的語句作為返回值钦扭。

func <- function(){
n<-1  
while (TRUE){
    if (n%%2==0){
      print('even number: ',n)
    }else{print('odd number: ',n)}
    if(n>10)
      print('too large, exit....')
      break
    n<-n+1
  }
}

apply家族

apply家族函數(shù)是進(jìn)行向量化運算的運算方法,而且由于其基于C語言編寫的床绪,與for循環(huán)相比客情,能大大地提高運算速度。apply家族函數(shù)眾多癞己,包括apply膀斋、sapplylapply痹雅、vapply仰担、mapplytapply绩社、rapply摔蓝、eapply,各個函數(shù)的用途如下圖所示愉耙。這里主要講一下應(yīng)用較多的applysapply函數(shù)贮尉。

1、apply

apply函數(shù)可以對矩陣朴沿、數(shù)據(jù)框猜谚、數(shù)組(二維、多維)悯仙,按行或列進(jìn)行循環(huán)計算龄毡,對子元素進(jìn)行迭代,并把子元素以參數(shù)傳遞的形式給自定義的FUN函數(shù)中锡垄,并返回計算結(jié)果沦零。使用方法如下:

apply(X, MARGIN, FUN, ...)
X 表示數(shù)組、矩陣或數(shù)據(jù)框
MARGIN 表示函數(shù)作用于行還是列货岭,1表示行路操,2表示列
FUN 作用于行或列的函數(shù)
... 表示函數(shù)的參數(shù)

> options(digits=2);student <- c('andy','lucy','mike','jacky');score <- c(88,92,67,75);df<-data.frame(student,score,stringsAsFactors=FALSE);df
  student score
1    andy    88
2    lucy    92
3    mike    67
4   jacky    75
> df$salary<-c(200,320,90,NA);df
  student score salary
1    andy    88    200
2    lucy    92    320
3    mike    67     90
4   jacky    75     NA
> average <- apply(df[,c(2:3)],2,mean,na.rm=TRUE);df<-rbind(df,c("average",average));df
  student score           salary
1    andy    88              200
2    lucy    92              320
3    mike    67               90
4   jacky    75             <NA>
5 average  80.5 203.333333333333
####這里需要注意的是由于行合并的時候用了c("average",average)疾渴,因此average數(shù)字也被換成了字符串,為了方便后續(xù)計算屯仗,最好還是將他們轉(zhuǎn)換為numeric
> df[,c(2,3)]<-apply(df[,c(2,3)], 2, as.numeric);df
  student score salary
1    andy    88    200
2    lucy    92    320
3    mike    67     90
4   jacky    75     NA
5 average    80    203

再來看一個稍微復(fù)雜點的例子搞坝,這回我們使用自定義的函數(shù),完成對矩陣的第一列加一魁袜,第二列等于行平均值:

###首先定義函數(shù)
func <- function(x, c1, c2){
  c(sum(x[c1], 1), x[c2]<-mean(x[c2]))
}

###使用自定義函數(shù)
> x <- cbind(x1 = 3, x2 = c(4:1, 2:5)); x
     x1 x2
[1,]  3  4
[2,]  3  3
[3,]  3  2
[4,]  3  1
[5,]  3  2
[6,]  3  3
[7,]  3  4
[8,]  3  5
> apply(x,1,func,c1='x1',c2=c('x1','x2'))
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]  4.0    4  4.0    4  4.0    4  4.0    4
[2,]  3.5    3  2.5    2  2.5    3  3.5    4
###另一種更簡單的方法
> x<-data.frame(x1=x[,1]+1,x2=rowMeans(x));x
  x1  x2
1  4 3.5
2  4 3.0
3  4 2.5
4  4 2.0
5  4 2.5
6  4 3.0
7  4 3.5
8  4 4.0

2桩撮、lapply

lapply函數(shù)是一個最基礎(chǔ)循環(huán)操作函數(shù)之一,用來對list峰弹、data.frame數(shù)據(jù)集進(jìn)行循環(huán)店量,并返回和X長度同樣的list結(jié)構(gòu)作為結(jié)果集。使用方法如下:

lapply(X, FUNC, ...)
X list鞠呈,data.frame數(shù)據(jù)結(jié)構(gòu)(使用data.frame時融师,作用于列)
FUN 作用函數(shù)
... 參數(shù)

> x <- list(a = 1:10, b = rnorm(6,10,5), c = c(TRUE,FALSE,FALSE,TRUE));x
$a
 [1]  1  2  3  4  5  6  7  8  9 10

$b
[1]  8.2 11.0 11.0 11.9 11.4  6.0

$c
[1]  TRUE FALSE FALSE  TRUE

> lapply(x, fivenum)
$a
[1]  1.0  3.0  5.5  8.0 10.0

$b
[1]  6.0  8.2 11.0 11.4 11.9

$c
[1] 0.0 0.0 0.5 1.0 1.0
#######################對矩陣使用會出現(xiàn)錯誤
> x <- cbind(x1=3, x2=c(2:1,4:5));x
     x1 x2
[1,]  3  2
[2,]  3  1
[3,]  3  4
[4,]  3  5
> class(x); lapply(x,sum)
[1] "matrix"
[[1]]
[1] 3

[[2]]
[1] 3

[[3]]
[1] 3

[[4]]
[1] 3

[[5]]
[1] 2

[[6]]
[1] 1

[[7]]
[1] 4

[[8]]
[1] 5

> x<-as.data.frame(x);lapply(x,sum)
$x1
[1] 12

$x2
[1] 12

3、sapply

sapply函數(shù)是一個簡化版的lapply蚁吝,sapply增加了2個參數(shù)simplify和USE.NAMES旱爆,主要就是讓輸出看起來更友好,返回值為向量窘茁,而不是list對象怀伦。

sapply(X, FUN, ..., simplify=TRUE, USE.NAMES = TRUE)
X 數(shù)組、矩陣庙曙、數(shù)據(jù)框
FUN 調(diào)用函數(shù)
... 函數(shù)參數(shù)
simplify 是否數(shù)組化空镜,當(dāng)值array時,輸出結(jié)果按數(shù)組進(jìn)行分組
USE.NAMES 如果X為字符串捌朴,TRUE設(shè)置字符串為數(shù)據(jù)名吴攒,F(xiàn)ALSE不設(shè)置

> x <- cbind(x1=3, x2=c(2:1,4:5));x
     x1 x2
[1,]  3  2
[2,]  3  1
[3,]  3  4
[4,]  3  5
###對矩陣進(jìn)行計算結(jié)果與lapply相同,無法得到想要的結(jié)果
> sapply(x, sum);
[1] 3 3 3 3 2 1 4 5
> sapply(data.frame(x), sum);
x1 x2 
12 12
###當(dāng)simplify=FALSE和USE.NAMES=FALSE時候砂蔽,那么sapply函數(shù)就等于lapply函數(shù)了
> sapply(data.frame(x), sum, simplify=FALSE, USE.NAMES=FALSE)
$x1
[1] 12

$x2
[1] 12

4洼怔、vapply

vapply類似于sapply,提供了FUN.VALUE參數(shù)左驾,用來控制返回值的行名镣隶,這樣可以讓程序更健壯。

vapply(X, FUN, FUN.VALUE, ..., USE.NAMES = TRUE)
X 數(shù)組诡右、矩陣安岂、數(shù)據(jù)框
FUN 自定義的調(diào)用函數(shù)
FUN.VALUE 定義返回值的行名row.names
… 函數(shù)參數(shù)
USE.NAMES 如果X為字符串,TRUE設(shè)置字符串為數(shù)據(jù)名帆吻,F(xiàn)ALSE不設(shè)置

#對數(shù)據(jù)框的數(shù)據(jù)進(jìn)行累計求和域那,并對每一行設(shè)置行名row.names
> x <- data.frame(cbind(x1=3, x2=c(2:1,4:5)));x
  x1 x2
1  3  2
2  3  1
3  3  4
4  3  5
> vapply(x,cumsum,FUN.VALUE=c('a'=0,'b'=0,'c'=0,'d'=0))
  x1 x2
a  3  2
b  6  3
c  9  7
d 12 12

轉(zhuǎn)自:
掌握R語言中的apply函數(shù)族

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市猜煮,隨后出現(xiàn)的幾起案子次员,更是在濱河造成了極大的恐慌败许,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淑蔚,死亡現(xiàn)場離奇詭異市殷,居然都是意外死亡,警方通過查閱死者的電腦和手機刹衫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門醋寝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人带迟,你說我怎么就攤上這事甥桂。” “怎么了邮旷?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蝇摸。 經(jīng)常有香客問我婶肩,道長,這世上最難降的妖魔是什么貌夕? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任律歼,我火速辦了婚禮,結(jié)果婚禮上啡专,老公的妹妹穿的比我還像新娘险毁。我一直安慰自己,他們只是感情好们童,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布畔况。 她就那樣靜靜地躺著,像睡著了一般慧库。 火紅的嫁衣襯著肌膚如雪跷跪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天齐板,我揣著相機與錄音吵瞻,去河邊找鬼。 笑死甘磨,一個胖子當(dāng)著我的面吹牛橡羞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播济舆,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼卿泽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吗冤?” 一聲冷哼從身側(cè)響起又厉,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤九府,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后覆致,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侄旬,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年煌妈,在試婚紗的時候發(fā)現(xiàn)自己被綠了儡羔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡璧诵,死狀恐怖汰蜘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情之宿,我是刑警寧澤族操,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站比被,受9級特大地震影響色难,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜等缀,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一枷莉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尺迂,春花似錦笤妙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至膳音,卻和暖如春辜限,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背严蓖。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工薄嫡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人颗胡。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓毫深,卻偏偏與公主長得像,于是被迫代替她去往敵國和親毒姨。 傳聞我的和親對象是個殘疾皇子哑蔫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

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