R語言-迴圈與條件
for (n in x) {expr}
R中最基本的是for迴圈,其中n為迴圈變數,x通常是一個序列。n在每次迴圈時從x中順序取值,代入到後面的expr語句中進行運算。下面的例子即是以for迴圈計算30個Fibonacci數。
x <- c(1,1)
for (i in 3:30) {
x <- x[i-1]+x[i-2]
}
例子1
pv<-c(1,1,2,3,1,1,15,7,18,1,1,2,3,1,1)
result<- ""
m<-1
for(i in pv){
if(i<=5){
result[m]<- "初級使用者";
} else if(i<=15){
result[m]<- "中級使用者";
} else{
result[m]<- "高階使用者";
}
m<-m+1
}
例子2
pv<-c(1,1,2,3,1,1,15,7,18,1,1,2,3,1,1)
result<-""
for(i in 1:length(pv)){
if(pv[i]<=5){
result[i]<- "初級使用者";
} else if(pv[i]<=15){
result[i]<- "中級使用者";
} else{
result[i]<- "高階使用者";
}
}
當不能確定迴圈次數時,我們需要用while迴圈語句。在condition條件為真時,執行大括號內的expr語句。下面即是以while迴圈來計算30個Fibonacci數。
x <- c(1,1)
i <- 3
while (i <= 30) {
x <- x[i-1]+x[i-2]
i <- i +1
}
例子3
pv<-c(1,1,2,3,1,1,15,7,18,1,1,2,3,1,1)
i<-1
result<-""
while(i<length(pv)){
if(pv[i]<=5){
result[i]<- "初級使用者";
} else if(pv[i]<=15){
result[i]<- "中級使用者";
} else{
result[i]<- "高階使用者";
}
i<-i+1
}
由此可以看出,for實際上是通過遍歷一個向量的方式來控制迴圈次數,while則是直接設定迴圈的範圍。for的應用基本可以覆蓋while,所以筆者更加傾向於使用for迴圈語句。
repeat-break迴圈語句
repeat是無限迴圈語句,並且會在達到迴圈條件後使用break語句直接跳出迴圈。例如:
pv<-c(1,1,2,3,1,1,15,7,18,1,1,2,3,1,1)
i<-1
result<-""
repeat{
if(i>length(pv)){ #設定迴圈結束時的跳出語句
break
}
if(pv[i]<=5){
result[i]<- "初級使用者";
} else if(pv[i]<=15){
result[i]<- "中級使用者";
} else{
result[i]<- "高階使用者";
}
i<-i+1
}
例項中的break也叫跳出迴圈命令,執行後將直接跳出迴圈語句。R語言還提供了一個next語句,執行後只會跳出本次迴圈,而不會跳出整個迴圈語句。
if (conditon) {expr1} else {expr2}
if語句用來進行條件控制,以執行不同的語句。若condition條件為真,則執行expr1,否則執行expr2。ifesle()函式也能以簡潔的方式構成條件語句。下面的一個簡單的例子是要找出100以內的質數。
x <- 1:100
y <- rep(T,100)
for (i in 3:100) {
if (all(i%%(2:(i-1))!=0)){
y <- TRUE
} else {y <- FALSE
}
}
print(x[y])
在上面例子裡,all()函式的作用是判斷一個邏輯序列是否全為真,%%的作用是返回餘數。在if/else語句中一個容易出現的錯誤就是else沒有放在}的後面,若你執行下面的示例就會出現錯誤。
logic = 3
x<- c(2,3)
if (logic == 2){
y <- x^2
}
else {
y<-x^3
}
show(y)
一個例子
本例來自於"introduction to Scientific Programming and Simulatoin Using R"一書的習題。有這樣一種賭博遊戲,賭客首先將兩個骰子隨機拋擲第一次,如果點數和出現7或11,則贏得遊戲,遊戲結束。如果沒有出現7或11,賭客繼續拋擲,如果點數與第一次扔的點數一樣,則贏得遊戲,遊戲結束,如果點數為7或11則輸掉遊戲,遊戲結束。如果出現其它情況,則繼續拋擲,直到贏或者輸。用R程式設計來計算賭客贏的概率,以決定是否應該參加這個遊戲。
craps <- function() {
#returns TRUE if you win, FALSE otherwise
initial.roll <- sum(sample(1:6,2,replace=T))
if (initial.roll == 7 || initial.roll == 11) return(TRUE)
while (TRUE) {
current.roll <- sum(sample(1:6,2,replace=T))
if (current.roll == 7 || current.roll == 11) {
return(FALSE)
} else if (current.roll == initial.roll) {
return(TRUE)
}
}
}
mean(replicate(10000, craps()))
從最終結果來看,賭客贏的概率為0.46,長期來看只會往外掏錢,顯然不應該參加這個遊戲了。最後要說的是,本題也可以用遞迴來做。