R是一种块状结构程序语言。块(block)由大括号划分,不过,当块只包含一条语句时大括号可以省略。
R语言的控制语句跟前文提到的ALGOL语言家族的控制语句非常相近。
►循环
先看下面这段程序:
> x <- c( 1, 2, 3, 4, 5 )
> for( n in x ){
+ print( n^2 )
+ }
[1] 1
[1] 4
[1] 9
[1] 16
[1] 25
这表示该循环对于向量x中的每个元素按都会有一次迭代,n会取遍x的各个元素值——在第一次迭代中,n=x[1];在第二次迭代中,n=x[2],依次类推。
C语言中的while和repeat在R中也是适用的,并且可以用break语句跳出循环。如下:
> i <- 1
> while( i <= 10 ){
+ i <- i+4+ }
> i
[1] 13
> i <-1
> while( TRUE ){
+ i <- i + 4
+ if( i > 10 )
+ break
+ }
> i
[1] 13
> i <- 1
> repeat{
+ i <- i + 4
+ if( i > 10 )
+ break
+ }
> i
[1] 13
注:repeat没有逻辑判断退出条件。必须利用break(或者类似return())的语句。
语句next,它会告诉解释器跳过本次迭代的剩余部分,直接进入循环的下一次迭代。这避免了使用复杂的if-then-else嵌套结构,不致让代码混乱不清。
►对非向量集合的循环
R并不支持直接对非向量集合的循环,但是有一些间接但简单的方式可以做到这点:
Ю使用lapply()。如果循环的每次迭代之间相互独立,就使用lapply()。可以允许任意顺序执行。
Ю使用get()。正如它的名字所暗示的一样,这个函数接受一个代表对象名字的字符串参数,然后返回该对象的内容。听起来虽然简单,但get()是一个非常有用的函数。
下面是一个使用get的例子:两个包含了统计数据的矩阵u和v,我们希望对每一个矩阵执行线性回归函数lm()。
> u <- matrix( c( 1, 2, 3, 1, 2, 4 ), nrow=3 )
> v <- matrix( c( 8, 12, 20, 15, 10, 2 ), nrow=3 )
> for( m in c( "u", "v" ) ){
+ z <- get( m )
+ print( lm( z[,2] ~ z[,1] ) )
+ }
Call:
lm(formula = z[, 2] ~ z[, 1])
Coefficients:
(Intercept) z[, 1] -0.6667 1.5000
Call:
lm(formula = z[, 2] ~ z[, 1])
Coefficients:
(Intercept) z[, 1] 23.286 -1.071
►if-else结构
if-else结构的语法如下:
> r <- 1> if( r == 1 ){
+ x <- TRUE
+ }else{ #else不要另起一行
+ x <- FALSE
+ }
> x
[1] TRUE
判断语句如果只有一条,可以省略大括号。
R语法分析器用else前的右括号来推断这是一个if-else结构而不只是if结构。在交互式模式中,如果没有了大括号,语法分析器会错误地认为这是if结构而进行相关的操作,这显然不是我们想要的结果。
上述代码可以简化成:
> r <- 1
> x <- if( r == 1 ) TRUE else FALSE
> x
[1] TRUE