对所有的编程语言而言,循环语句是非常重要的。因为我们使用各种循环来处理各类数据。例如从一个数据集中不断地取出各类子集。典型的例子是如果我们有一个数据集包含5000支股票,我们计划计算每一只股票的各种特征。为此我们可以用循环语句从1到5000循环5000次。其他应用还包括:合并不同的数据集,或按各种条件重新定义程序流程。
最常用的两个循环是for()循环和while()循环。下面为在屏幕上打印3个值的最简单的for()循环。
> for(i in 1:3) print(i)
[1] 1
[1] 2
[1] 3
for()是最为常用的循环语句,上面的单行代码相当于以下两行。
> x<-1:3
> for(i in x)print(i)
for()是关键词,
为变量,
的取值从1到3,每次取一个值。x本身是一个向量。向量是一个列变量。其维数是
×1或1×
。下面是另一个类似的例子,其中tickers是一个字符向量。
> tickers<-c("DELL","IBM","C","MSFT")
> for(ticker in tickers) print(ticker)
[1] "DELL"
[1] "IBM"
[1] "C"
[1] "MSFT"
在下面的程序中,
从1到
每次取一个值,其中
是
的总观测值的个数。
> x<-5:15
> n<-length(x)
> for(i in 1:n) print(x[i])
更为简洁的语句如下:
> x<-5:15
> for(i in x) print(i)
对于占多行的程序,我们使用一对花括号{}来包含这些命令行。
for(i in 1:10){
#
# add your codes here
#
print(i)
}
在R语言中,有一些预先定义好的数据集。例如,名为LETTERS的字符数据集包含26个大写字母。而letters包含26个小写字母。
> LETTERS
[1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N"
[15] "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
> letters
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
[15] "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
> typeof(letters)
[1] "character"
> length(letters)
[1] 26
以下代码显示了如何用for()循环打印各个字母。为节省篇幅,我们只显示了最前面的6个字母。
> for(letter in letters) print(letter)
[1] "a"
[1] "b"
[1] "c"
[1] "d"
[1] "e"
[1] "f"
当使用cat()函数而不是print()函数时,我们可以将所有26个字母打印在一行中。
> for(letter in letters) cat(letter)
abcdefghijklmnopqrstuvwxyz>
如果我们打算每行仅仅打印一个字母,我们可以添加一个换行符号("\n")。为节省篇幅,下面我们只显示了最前面的6个字母。
> for(letter in letters) cat(letter, "\n")
a
b
c
d
e
f
如果我们想以从Z~A的顺序打印字母,可以用以下语句。
> for(i in 1:26)print(LETTERS[27-i])
[1] "Z"
[1] "Y"
[1] "X"
[1] "W"
[1] "V"
[1] "U"
两个百分比%%,放在一起为取余函数。如给定两个整数值
和
,对于
%%
而言,我们得到的是将
除以
以后而余下的整数值。例如,15%%10结果是5,9%%4结果为1。
> 15%%10
[1] 5
> 9%%4
[1] 1
如果我们想将5个字母打印在一行中,可以在5个字母后添加一个换行符合,"\n"。见下面语句。
n<-length(letters)
for(i in 1:n){
cat(letters[i])
if(i%%5==0) cat("\n")
}
abcde
fghij
klmno
pqrst
uvwxy
z>
双循环的是常见的语句之一。例如我们有500只股票,想计算它们从2007年~2017年每年的市场风险。我们可以分成两个循环:第一个循环从1到500,第二个循环从2007年到2017年。对于双循环,
同样,正确缩进的代码会使我们的程序更具可读性。
> n1<- 1:500
> n2<- 2007:2017
> for(i in n1) {
for(j in n2){
#
# your codes here
#
cat(i,j,"\n")
}
}
1 2007
1 2008
1 2009
1 2010
1 2011
1 2012
1 2013
为节省篇幅,上面我们只显示少数几组输出。在第9章中,我们将介绍如何计算股票的市场风险。在下列中,我们打算将主要对角变量y[
,
]加上5,其中
=1, 2, …, 5的方矩阵。方阵的主要对角线是从左上角(NW,西北)到右下角(SE,东南)。为此,我们先生成一个方阵。
> x<-1:49 # x is a vector
> y<-matrix(x,7,7,byrow=T) # y is 7 by 7 matrix
> y
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 2 3 4 5 6 7
[2,] 8 9 10 11 12 13 14
[3,] 15 16 17 18 19 20 21
[4,] 22 23 24 25 26 27 28
[5,] 29 30 31 32 33 34 35
[6,] 36 37 38 39 40 41 42
[7,] 43 44 45 46 47 48 49
语句byrow=T是指按行排列。即第1行,第2行,等等。以下是为主对角线上的数据项加上5的代码。
n1<-nrow(y)
n2<-ncol(y)
for(i in 1:n1) {
for(j in 1:n2){
if(i==j) y[i,j]=y[i,j]+5
}
}
下面检验我们是否成功地将5添加到这些值上了。
> y
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 6 2 3 4 5 6 7
[2,] 8 14 10 11 12 13 14
[3,] 15 16 22 18 19 20 21
[4,] 22 23 24 30 26 27 28
[5,] 29 30 31 32 38 34 35
[6,] 36 37 38 39 40 46 42
[7,] 43 44 45 46 47 48 54
下面是一个使用while循环的例子。对while()循环而言,注意当while()条件不成立的情况是否可以满足,否则就会变成死循环。
i <- 0
while(i<15) {
i<- i+2
print(i)
}
请思考,下面的代码有什么问题?
j <- 20
while(j>10) {
print(j+2)
}
要停止当前的程序,我们可以单击菜单栏上的“Misc”,然后选择“Stop current calculation”,如图3-1所示。
图3-1 Misc菜单
或者干脆按Esc键。第3种方法是单击菜单栏上的红色停止键,如图3-2所示。
图3-2 STOP按钮
设置if()stop()语句,会使我们的编程调试工作更有效率。例如我们生成一个函数将输入数值翻倍。
> dd<-function(x)x*2
> dd(3.4)
[1] 6.8
但当你输入字符变量时,就会有出错信息。
> dd("good")
Error in x * 2 : non-numeric argument to binary operator
为此,我们可以用函数if()stop()及is.numeric()函数来解决这个问题。
dd<-function(n){
if (is.numeric(n)==FALSE) stop("Input should be numeric!")
return(2*n)
}
激活该函数之后,我们可以使用以下两个命令进行测试:一个是整数输入,另一个用于字符输入。
> dd(2)
[1] 4
> dd("live")
Error in double("live") : Input should be numeric!
我们可以用下列函数计算未来价值:
(3-1)
在上式中,
是未来值,
是现值,
是利率,
是周期数。如果我们不允许负的利率存在那在这种情况下,我们就可以使用if()和stop()函数。
fv_f<-function(pv,r,n){
if(r<0)stop("interest is negative")
return(pv*(1+r)^n)
}
我们可以通过输入负利率来测试。
>fv_f(100,0.1,1)
[1] 110
> fv_f(100,-0.1,1)
Error in fv_f(100, -0.1, 1) : interest is negative
一个向量被定义为“列变量”,我们可使用length()函数来得出它的长度。
> x<-c(1,2,4.5,7,9)
> x
[1] 1.0 2.0 4.5 7.0 9.0
> length(x)
[1] 5
矩阵是一个二维数据集(变量)。我们可以使用cbind()函数来将两个向量联成一个矩阵。如cbind(vector1, vector2)。
> x<-c(1,2,4.5,7,9)
> y<-c(0.3,0.2,0,4,5)
> z<-cbind(x,y)
> z
x y
[1,] 1.0 0.3
[2,] 2.0 0.2
[3,] 4.5 0.0
[4,] 7.0 4.0
[5,] 9.0 5.0
在上述情况下,
和
都是向量,而
是矩阵。有时我们需要知道向量包含的数据点(值)(即向量的长度)。在这些情况下,我们用length()函数。
> x<-c(1:20,4:22,9)
> n<-length(x)
> n
[1] 40
对于一个矩阵而言,我们使用nrow()函数来得出一矩阵的行数和用ncol()函数来得出一矩阵的列数,详见下面示例。
> x<-matrix(0,3,4)
> x
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 0 0 0 0
[3,] 0 0 0 0
> nrow(x)
[1] 3
> ncol(x)
[1] 4
要得到一个矩阵的行数和列数,我们可以使用dim()函数。
> x<-matrix(0,3,4)
> dim(x)
[1] 3 4
> n<-dim(x)
> n[1]
[1] 3
> n[2]
[1] 4
if()和if()-else()函数等条件通常用于处理数据,或重定义程序的流程。假设我们有一个包含1000只股票的数据集,但我们可能只关注其中的某股票,例如要选择IBM在2010年的数据。为此,我们的条件可设定为:if(ticker=="IBM"&year==2010),其中&是逻辑与。下面是使用if()函数的最简单的例子。
> x<-10
> if(x>0) print("x>0")
假设我们有以下两列的简单数据集。
> year<-c(1991,1992,1993,1994)
> ret<-c(0.01,0.02,0.03,0.034)
> data<-cbind(year,ret)
> data
year ret
[1,] 1991 0.010
[2,] 1992 0.020
[3,] 1993 0.030
[4,] 1994 0.034
我们想要得到一个数据子集,比如1992年以后的数据,可以用subset()函数加上一个条件语句。
> x<-subset(data,year>1992)
> x
year ret
[1,] 1993 0.030
[2,] 1994 0.034
在下面的代码中,我们有一个名为decision的变量。其默认值为“rejecttheproject”。当其NPV为正时,我们接受该项目。在第6章中,我们将介绍该NPV规则:如果NPV>0,接受该项目;如果NPV≤0,拒绝该项目。
>decision<-"reject the project"
>if(npv>0) decision<-"accept the project"
>print(decision)
if-else是另一种广泛使用的结构,参见下面这个极为简单的例子。
if(x>0){
print("x>0")
# your codes here
} else {
print("x<=0")
# your codes here
}
在上面的代码中,我们将x值分为两组:正值和非正。
对于多组分类,我们可以将多个if()函数组合在一起。下面,我们生成将百分制成绩换为相应的字母成绩。
letter_grade<-function(grade){
if(grade>=90){
final<-"A"
} else if(grade>=80){
final<-"B"
} else if (grade>=70){
final<-"C"
} else if (grade>=60){
final<-"D"
} else{
final<-"Fail"
}
return(final)
}
调用这个函数很简单。
> letter_grade(90)
[1] "A"
> letter_grade(89)
[1] "B"
> letter_grade(79)
[1] "C"
> letter_grade(50)
[1] "Fail"
在R中,逻辑或意味着如果满足条件A或B。
> x=1
> y=-3
> if(x>0 | y>0) cat("x=",x,"y=",y,"\n")
x= 1 y= −3
假设我们试图从所有美国股票中选择样本数据。根据研究主题,我们对纽约交易所上市或美国交易所上市的股票感兴趣。对一个名为EXCHAGE的变量,NYSE(纽约证券交易所)的值为1,AMEX(美国证券交易所)的值为2,NASDAQ(纳斯达克)为3。那么我们可以有以下代码:
>x2<-subset(x,EXCHAGE==1 | EXCHAGE==2)
在R中,我们使用&符号来表示逻辑和。
> x<-1
> y <- -3
> if(x>0 & y>0) print("both positive")
我们可以将有不同类型的条件组合在一起。例如对两个变量(
和
),在两者都应该是正数,且
是偶数时,我们打印“pass”。
> x<-7
> y<-9
> if((x>0 | y>0) & x%%2==0) print("pass")
本文摘自:《R语言金融分析与建模》
大数据时代已经到来,如何基于数据完成科学、有效的决策是多数人应该学习和掌握的新技能。开源软件R是世界上流行的数据分析、统计计算及制图语言,几乎能够完成任何数据处理工作。近来R在编程语言排行榜的排名也逐渐上升,可见R的影响力和受欢迎程度都有提升。R可安装并运行于所有主流平台,为我们提供了成千上万的专业模块和实用工具,是数据挖掘、数据分析领域的好工具。
本书注重基础知识和实用技能,系统地介绍了R的特性和它的强大功能,引导读者由浅入深地学习R语言并掌握R在金融领域的应用。本书的作者不仅有丰富的教学经验,而且对R的金融应用有着深入的见解。
本书系统地介绍了R的包与编程方法,并通过丰富的金融案例展示了R在金融分析和金融建模方面的应用。本书分为5篇,共30章,从R语言基础、金融模型及基础知识、数据及相关操作、R在金融建模中的应用和R技能几个主题出发,讲解了R在金融量化中的应用和技巧。
本书适合从事金融数据分析、金融量化建模的读者学习。通过阅读本书,读者将了解全球化的金融市场数据,学习多样的金融建模思想和解决方案。