1. 程式人生 > >R語言-迴圈與條件

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迴圈語句。在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,長期來看只會往外掏錢,顯然不應該參加這個遊戲了。最後要說的是,本題也可以用遞迴來做。