<- 賦值-- 如 A <- B 就是 A=B
{expr_1; ...; expr_m} -- 多個指令可以用 {}括起來,用 ; 分開。
> if (expr_1) expr_2 else expr_3
&& 為 and, || 為 or。 & 和 | 將用於向量的所有元素,而 && 和 || 僅用於長度為1的向量。
ifelse
它的使用方式是 ifelse(condition, a, b),最終返回一個和最長的參數向量同長的向量。 condition[i] 為真時,該向量對應的元素是 a[i],否則為 b[i]。
for (name in expr_1) expr_2
另外一種迴圈語句包括
> repeat expr
和語句
> while (condition) expr
關鍵字 break可以用於結束任何迴圈。它是結束 repeat 迴圈的唯一辦法。 關鍵字 next 可以用來結束一次特定的迴圈,然後直接跳入 “下一次”迴圈。
> name <- function(arg_1, arg_2, ...) expression
Example:
> add2 <- function(n1, n2) {
ret1 <- n1 + n2
}
> temp <- add2(10,20); temp
參數命名和預設值
參數可以用“name=object”的方式給出,此時可為任何順序。如果有下面方式定義的函數 fun1
> fun1 <- function(data, data.frame, graph, limit) {
[function body omitted]
}
那麼函數將會被好幾種方式調用,如
> ans <- fun1(d, df, TRUE, 20)
> ans <- fun1(d, df, graph=TRUE, limit=20)
> ans <- fun1(data=d, limit=20, graph=TRUE, data.frame=df)
上面所有的方式是相同的。
許多時候,參數會被設定一些預設值。如果預設值適合你要做的事情,你可以省略這些參數。例如,函數 fun1 用下面的方式定義
> fun1 <- function(data, data.frame, graph=TRUE, limit=20) { ... }
它可以被如下命令調用
> ans <- fun1(d, df)
這和前面的三種情況等價。
> ans <- fun1(d, df, limit=10)
這就改變了一個預設值。
特別說明一下,預設值可以是任何運算式,甚至是函數本身所帶有的其他參數;它們沒有要求是常數。我們的例子採用常數只是使問題簡單容易說明。
Scope
在函數內部的變數可以分為三類:形式參數,局部變數和自由變數。形式參數是出現在函數的參數列表中的變數。它們的值由實際的函數參數綁定形式參數的過程決定的。局部變數由函數內部的運算式的值決定的。既不是形式參數又不是局部變數的變數是自由變數。自由變數如果被賦值將會變成局部變數。考慮下面的函數定義過程。
f <- function(x) {
y <- 2*x
print(x)
print(y)
print(z)
}
在這個函數中,x 是形式參數,y 是局部變數,z 是自由變數。
在 R 裏面,可以利用函數被創建的環境中某個變數的第一次出現解析一個自由變數的綁定。這稱為詞法作用域(lexical scope)。我們可以定義一個函數 cube。
cube <- function(n) {
sq <- function() n*n
n*sq()
}
函數 sq 中的變數 n 不是函數的參數,因此它是自由變數。一些作用域的原則可以用來確定和它相關的值。在靜態作用域 (S-Plus),這個值指的是一個和總體變數 n 相關的值。在詞法作用域(R),它指的是函數 cube 的參數。因為當 sq 定義的時候,它會動態綁定參數 n。在 R 裏面解析和在 S-Plus 裏面解析不同點在於 S-Plus 搜索總體變數 n 而 R 在 cube 調用時首先尋找環境創建的變數 n。
## 首先用 S 解析
S> cube(2)
Error in sq(): Object "n" not found
Dumped
S> n <- 3
S> cube(2)
[1] 18
## 同樣的函數在 R 中解析
R> cube(2)
[1] 8
辭彙作用域會給予函數可變狀態(mutable state)。
<<- 是一個特別的賦值操作符號,它會往上層尋找變數。
open.account <- function(total) {
list(
deposit = function(amount) {
if(amount <= 0)
stop("Deposits must be positive!\n")
total <<- total + amount # 尋找到上一層 total並賦予值
cat(amount, "deposited. Your balance is", total, "\n\n")
},
withdraw = function(amount) {
if(amount > total)
stop("You don't have that much money!\n")
total <<- total - amount
cat(amount, "withdrawn. Your balance is", total, "\n\n")
},
balance = function() {
cat("Your balance is", total, "\n\n")
}
)
}
> ross <- open.account(100)
> robert <- open.account(200)
> ross$withdraw(30)
30 withdrawn. Your balance is 70
> ross$balance()
Your balance is 70
> robert$balance()
Your balance is 200
> ross$deposit(50)
50 deposited. Your balance is 120
> ross$balance()
Your balance is 120
> ross$withdraw(500)
錯誤在ross$withdraw(500) : You don't have that much money!
>