Thursday, September 4, 2014

R学习笔记(二)

一、控制结构

在正常情况下,R程序中的语句是从上到下顺序执行的,但有些情况下可能需要重复执行某些语句,就需要控制语句。常见的控制结构有:if,else;for;while;repeat,break;next,return等。
if,else:条件执行结构,条件为真时执行语句,条件为假时执行另外的语句。语法为:if(cond) statement1 else statement2
for:循环重复地执行一个语句,直到某个变量的值不再包含在序列seq中为止。语法为:for (var in seq) statement
1
2
for (i in 1:10) print("Hello") ##输出10次Hello
for (i in 1:10) print(i) ##输出1到10的自然数
while:循环重复地执行一个语句,直到条件不为真为止。语法为:while(cond) statement
1
2
3
4
5
count <- 0
while(count < 10) {
print(count)
count <- count + 1
} ##输出结果为0到9的自然数
需要注意的是使用while循环的时候必须确保它在某个时刻可以停止,否则语句将永远执行下去。必须小心使用!
repeat,break:在有限循环中使用,通常的统计运用中并不常用。唯一可以中止repeat语句的是break。
1
2
3
4
5
6
7
8
9
10
x0 <- 1
tol <- 1e-8
repeat {
x1 <- computeEstimate()
if(abs(x1 - x0) < tol) {
break
} else {
x0 <- x1
}
}
next,return:next用来跳过循环中的迭代,return指示函数应该退出并返回相应值。
1
2
3
4
5
for(i in 1:100) {
if(i <= 20) {
next}
print(i)
} ##结果为21到100的自然数

二、函数

基本结构:
myfunction <- function(arg1, arg2, ... ){
statements
return(object)
}
函数是R中最主要的对象,用户可以编写自己的函数。具体情况还要具体分析,此部分从略。

三、作用域规则

本部分引自丁国徽翻译的R语言定义-作用域规则,我做了修改。英文原文在这里
作用域或作用域规则简单说就是求值程序为一个符号 寻找值所用规则的集合。每种计算机语言都有这样的一套规则。在R里面,这个规则非常的简单,但也确实存在一些不同寻常的机制。
R沿用一套称之为词法作用域的规则。这表明在表达式创建时变量的有效绑定可用来为表达式中任何自由符号提供值。
作用域的许多有趣的性质都和函数的求值有关,现在我们集中描述这个问题。一个符号要么是有约束的要么是自由的。一个函数的所有形式参数在函数主体中提供了被约束的符号。任何其它在函数主体里面的符号要么是局部变量要么是自由变量。局部变量是在函数中定义的变量。因为R有变量的形式定义,它们只在需要的时候才使用,这样就很难区分一个变量是否是局部变量。局部变量首先需要定义,典型的做法是让它们处在一个赋值操作的左边。
在求值过程中,如果发现一个自由变量,那么R会去给它找一个值。作用域规则决定了这个过程如何进行。在R里面,函数的环境首先会被搜索,然后是它的外围,如此直到全局环境。
全局环境指向一个为某个匹配符号逐步搜索的环境的搜索列表。 第一个匹配上的值会被采用。
当这些规则结合了函数能以值的形式从其它函数返回的事实,确实不错。但是首先,你必须获得所有特性。
一个简单的例子是,
1
2
3
4
5
6
7
f <- function(x) {
y <- 10
g <- function(x) x + y
return(g)
}
h <- f()
h(3)
一个非常有意思的问题是,给h求值会怎样?为了描述这个,我们需要考虑更多的东西。在函数主体里面,变量可以被约束为局部的或自由的。被约束的变量是这些匹配函数形式参数的变量。局部变量指的是那些在函数主体内创建和定义的变量。自由变量指的是那些既不是局部也不是被约束的变量。当一个函数主体被求值时可以确定一个局部或被约束变量的值。作用域规则决定了语句如何为自由变量找恰当的值。
当h(3)被求值,我们发现它的主体就是g的主体。在该主体中,x和y都是自由的。在一个词法作用域定义的语言中,x的值为3而y和的值为10,因此h(3)返回值为13。在R里面,这就是实际运行过程。
这一节里的Optimization Application没有搞懂。

四、loop函数

lapply: 遍历列表并为函数的每个元素赋值,返回值均为list。sapply本质上与lapply没有区别,是lapply输出结果的简化。
1
2
3
4
5
6
7
8
9
10
11
12
13
> x <- list(a = 1:4, b = rnorm(10), c = rnorm(20, 1), d = rnorm(100, 5))
> lapply(x, mean)
$a
[1] 2.5
$b
[1] 0.06082667
$c
[1] 1.467083
$d
[1] 5.074749
> sapply(x, mean)
a b c d
2.50000000 0.06082667 1.46708277 5.07474950
apply函数常用于矩阵行列运算,也可用于一般数组。使用格式为:function (X, MARGIN, FUN, ...)
X是一个数组;MARGIN:1表示行,2表示列;
FUN是即将运行的函数;...是其他进入函数FUN的分量。
1
2
3
4
5
> x <- matrix(1:200, 20, 10) ##赋值x为20×10的矩阵
> apply(x, 1, mean) ##求矩阵x每行均值,相当于rowMeans(x)
 [1] 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
> apply(x, 2, mean)##求矩阵x每列均值,相当于colMeans(x)
 [1] 10.5 30.5 50.5 70.5 90.5 110.5 130.5 150.5 170.5 190.5
tapply用于对向量子集的函数,其使用格式为function (X, INDEX, FUN = NULL, ..., simplify = TRUE),其中X是一向量,INDEX是与X有相同长度的因子;FUN是需要计算的函数;simplify是逻辑变量,取值为为TURE(默认)或FALSE。
tapply常见于方差分析中对各个组别进行mean、var(sd)的计算。
split根据某些条件因子把向量或其他对象分成组,其使用格式为function (x, f, drop = FALSE, ...),其中x是向量(或list)或数据框;f是一个或一列因子;drop取值为为FALSE(默认)或TRUE。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
> x<-c(1:30)
> y<-gl(3,10) ##gl的意思:function (n, k, length = n * k, labels = 1:n, ordered = FALSE)
> tapply(x,y,mean) ## 求x中1到10、11到20、21到30这三部分均值
 1 2 3
 5.5 15.5 25.5
> tapply(x,y,mean,simplify=FALSE) ##不简化的结果
$`1`
[1] 5.5
$`2`
[1] 15.5
$`3`
[1] 25.5
> tapply(x, y, range) ##数组的分界
$`1`
[1] 1 10
$`2`
[1] 11 20
$`3`
[1] 21 30
> split(x,y) ##按照y的格式为x分组
$`1`
 [1] 1 2 3 4 5 6 7 8 9 10
$`2`
 [1] 11 12 13 14 15 16 17 18 19 20
$`3`
 [1] 21 22 23 24 25 26 27 28 29 30
> lapply(split(x, y), mean) ##求x分组后各组的均值
$`1`
[1] 5.5
$`2`
[1] 15.5
$`3`
[1] 25.5
1
2
3
4
5
6
7
8
9
10
11
12
> library(datasets)
> s <- split(airquality, airquality$Month) ## s为按月分组的airquality
> sapply(s, function(x) colMeans(x[, c("Ozone", "Solar.R", "Wind")])) ##求各月各项指标平均值(列均值)
 5 6 7 8 9
Ozone NA NA NA NA NA
Solar.R NA 190.16667 216.483871 NA 167.4333
Wind 11.62258 10.26667 8.941935 8.793548 10.1800
> sapply(s, function(x) colMeans(x[, c("Ozone", "Solar.R", "Wind")],na.rm=TRUE)) ## 除去缺失值后再求
 5 6 7 8 9
Ozone 23.61538 29.44444 59.115385 59.961538 31.44828
Solar.R 181.29630 190.16667 216.483871 171.857143 167.43333
Wind 11.62258 10.26667 8.941935 8.793548 10.18000
mapply是一个多变量应用中的对一组适用的函数在并行排序参数。其使用格式为function (FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE,USE.NAMES = TRUE),FUN和...含义同上,其中MoreArgs为其他应用于FUN的参数。

五、调试(debugging)工具

R中最重要的几个调试工具:
traceback: prints out the function call stack after an error occurs; does nothing if there’s no error
debug: flags a function for “debug” mode which allows you to step through execution of a function one line at a time
browser: suspends the execution of a function wherever it is called and puts the function in debug mode
trace: allows you to insert debugging code into a function a specific places
recover: allows you to modify the error behavior so that you can browse the function call stack

No comments:

Post a Comment