R 语言的控制结构
条件
if-else 结构
if(<condition>) {
## do something
}else{
## do something else
}
if(<condition1>) {
## do something
} else if(<condition2>) {
## do something different
}else{
## do something different
}
循环
for 循环
x <- c("a", "b", "c", "d")
for(i in 1:4) {
print(x[i])
}
for(i in seq_along(x))
{
print(x[i])
}
for(letter in x) {
print(letter)
}
while 循环:
count <- 0
while(count < 10) {
print(count)
count <- count + 1
}
repeat 循环:
x0<-1
tol <- 1e-8
repeat {
x1 <- computeEstimate()
if(abs(x1 - x0) < tol) {
break
}else{
x0<-x1
}
}
next 用于跳过本次循环,开始下一个循环;return 是直接返回
函数 function
格式为:
f <- function(<arguments>) {
## Do something interesting
}
函数的参数可以设定默认值
参数具有 lazy evaluation 的特性,如果某个参数在函数中没有用到,那调用时可以不传入该参数,函数不会报错。
…参数一般用来传递给内部调用的其它函数
Scoping Rules
符号与值的绑定
R把一个符号绑定到一个值上,是通过一系列的 environments找到合适的值。当在 shell 下使用一个变量时,大概的过程是:
- 查找全局的 environment, 是否有值匹配该变量符号;
- 在 search list 中,查找每个 package 的 namespace
search()可以查找当前的 search list 情况:
- global environment或user workspace通常是 search list 的第一个元素,base包总是最后一个元素。
- 当用户使用 library 加载时,该 package 的 namespace 会在 search list 的第2位上,其它的元素会相应后移。
- R 对于函数和非函数有不同的 namespace,所以会同时有一个叫 c 的对象和叫 c 的函数。
Scoping Rules
scoping rules决定了在函数中,一个值如何与 free variable建立关联。
R 使用lexical scoping和static scoping,一个可选的方案dynamic scoping。
Scoping Rules 决定了 R如何使用search list为绑定符号和值。
Lexical Scoping
如下面的函数:
f <- function(x, y) {
x^2+y/z
}
变量 z 在函数参数中未定义,但是直接使用了,这种变量称为free variable。
Scoping Rules定义了这种 free variable 是如何赋值的
Lexical scoping的意思是:
the values of free variables are searched for in the environment in which the function was defined.
environment 是一组键值对的组合,a collection of (symbol, value) pairs
每个 environment 有它的父 environment,一个environment 可能有多个子 environment;
没有父 environment 的 environment,是一个空的 environment
function+environment = a closure or function closure
查找 free variable 的值的过程:
- If the value of a symbol is not found in the environment in which a function was defined, then the
search is continued in the parent environment. - The search continues down the sequence of parent environments until we hit the top-level environment; this usually the global environment (workspace) or the namespace of a package.
- After the top-level environment, the search continues down the search list until we hit the empty environment. If a value for a given symbol cannot be found once the empty environment is arrived at, then an error is thrown.
R Scoping Rules
When a function is defined in the global environment and is subsequently called from the global environment, then the defining environment and the calling environment are the same. This can sometimes give the appearance of dynamic scoping.
- In R, all objects must be stored in memory
- All functions must carry a pointer to their respective defining environments, which could be anywhere
- In S-PLUS, free variables are always looked up in the global workspace, so everything can be stored on the disk because the “defining environment” of all functions is the same.
Lexical scoping summary
- Objective functions can be “built” which contain all of the necessary data for evaluating the function
- No need to carry around long argument lists — useful for interactive and exploratory work.
- Code can be simplified and cleand up
Coding Standards for R
- Always use text files / text editor
- Indent your code
- Limit the width of your code (80 columns?)
- Limit the length of individual functions
Date and Time
日期用 Date 类表示,它的内部是记录自从1970-1-1开始的天数
时间用POSIXct或者POSIXlt类表示,内部记录的是以从1970-1-1开始的秒数
x <- as.Date("1970-01-01")
- POSIXct is just a very large integer under the hood; it use a useful class when you want to store times in something like a data frame
- POSIXlt is a list underneath and it stores a bunch of other useful information like the day of the week, day of the year, month, day of the month
Times can be coerced from a character string using the as.POSIXlt or as.POSIXct function.
x <- Sys.time()
[1] "2013-01-24 22:04:14 EST"
p <- as.POSIXlt(x)
names(unclass(p))
[1] "sec" "min" "hour" "mday" "mon"
[6] "year" "wday" "yday" "isdst"
p$sec
[1] 14.34
strptime函数用来转换日期格式:
datestring <- c("January 10, 2012 10:40", "December 9, 2011 9:10")
x <- strptime(datestring, "%B %d, %Y %H:%M")
x