|
相比下拉菜单式的程序, R的一个优势在于它可以把一系列连续的操作简
单的程序化. 这一点上和所有其他计算机编程语言是一致的, 但R有一些特性
使得非专业人士也可以很简单的编写程序.
和其他编程语言一样, R 有一些和C语言类似的控制结构. 假定我们有一
个向量x, 对于向量x 中值为b的元素, 我们我们把0赋给另外一个等长向量y的
对应元素, 否则赋1. 我们首先创建一个与向量x等长的向量y:
y <- numeric(length(x))
for (i in 1:length(x)) if (x[i] == b) y[i] <- 0 else y[i] <- 1
几个指令可以放在一个大括弧里面:
for (i in 1:length(x)) {
y[i] <- 0
...
}
if (x[i] == b) {
y[i] <- 0
...
}
另外一种可能的情况是当条件为真的时候一条指令才执行:
while (myfun > minimum) {
...
}
但是, 由于R的一些特性, 在很多情况下循环和控制结构可以避免: 向量
化. 向量化使得循环暗含在表达式中, 前面的例子中已经多次采用了. 比如, 两
个向量之和:
> z <- x + y
这种加和可以通过循环结构来实现, 就像很多编程语言采用的策略一样:
> z <- numeric(length(x))
> for (i in 1:length(z)) z[i] <- x[i] + y[i]
在这个例子中, 由于要用到向量的下标系统, 有必要预先创建一个向量z.
显然, 这种显式的循环仅仅用于向量x 和y 等长的情况: 如果不是这样程序代
码需要改变, 而第一种表达方式在任何情况下都成立26.
条件语句(if ... else) 可以用逻辑索引向量代替; 同样上面的例子:
> y[x == b] <- 0
> y[x != b] <- 1
除了让代码更简洁, 向量化的表达式在计算上效率更高, 特别是大数据量
的数据集.
有多个`apply' 形式的函数用于避免使用代码的显式循环结构. apply 作
用于矩阵的行或者/和列, 它的语法规则是apply(X, MARGIN, FUN, ...), 其
中X是一个矩阵, MARGIN 表明是对行(1) 还是列(2), 或者二者(c(1, 2))进行操
作, FUN 是一个函数(或操作符, 但是这种情况下操作符要在一个括弧里面指
定27) , ... 是函数FUN可能的参数. 一个简单的例子如下.
> x <- rnorm(10, -5, 0.1)
> y <- rnorm(10, 5, 2)
> X <- cbind(x, y) # 矩阵X的列名保持"x" 和"y"
> apply(X, 2, mean)
x y
-4.975132 4.932979
> apply(X, 2, sd)
x y
0.0755153 2.1388071
lapply() 可以用于一个列表对象: 它的语法类似apply 并且返回一个列
表对象.
> forms <- list(y ~ x, y ~ poly(x, 2))
> lapply(forms, lm)
[[1]]
26译者注:如果对R的向量循环使用方式不了解的话,这里要小心一点.
27译者注:我没有用过这种情况,原文为\or an operator, but in this case it must be speci¯ed
within brackets"
Call:
FUN(formula = X[[1]])
Coefficients:
(Intercept) x
31.683 5.377
[[2]]
Call:
FUN(formula = X[[2]])
Coefficients:
(Intercept) poly(x, 2)1 poly(x, 2)2
4.9330 1.2181 -0.6037
sapply() 是函数lapply() 一个更为灵活的变种, 它可以接受向量或者矩
阵作为主要参数, 并且返回形式更为友好的结果, 常常是表格方式. |
|