控制流
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
煞茫、for
、if
后面的條件語句都需要用小括號括起來摄凡。
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
膀斋、sapply
、lapply
痹雅、vapply
仰担、mapply
、tapply
绩社、rapply
摔蓝、eapply
,各個函數(shù)的用途如下圖所示愉耙。這里主要講一下應(yīng)用較多的apply
和sapply
函數(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ù)族