|
用R语言分析股票指数变化
杨旭东(2012-3-6)
今天商学院的一个同学写毕业论文时遇到点麻烦,于是找我帮忙。要求是这样的:已知一段时间内每日的股票开盘和收盘指数,以及若干股票的招股开始日期(发行日)和上市日期,要求这两个日期之间股票指数的变化情况。如下图所示,其中浅绿色的部分是我用R语言算出来的。

计算公式如下:指数变化=(上市首日收盘指数-发行日开盘指数)/ 发行日开盘指数。
首先,准备两份数据:
1.每日的股票开盘和收盘指数,即上图中的第1、2、5列,保存在D盘下面,文件名为stock1.csv(用Excel另存为csv格式(逗号分隔的数据))。
2.股票的上市日期和发现日期,即上图中的第6、8列,保存为“D:\stock.txt”(用制表符分隔数据项)。
接着在R语言控制台中设置好工作目录:
> setwd("D:\\") #注意这里转义字符‘\’的使用
> getwd()
[1] "D:/"
读入第一份数据:
dict <-read.csv("stock1.csv")
> dict
日期 开盘收盘
1 2001-11-1 1692.35 1707.75
2 2001-11-2 1703.92 1691.35
3 2001-11-5 1687.84 1679.57
4 2001-11-6 1678.17 1671.27
5 2001-11-7 1669.42 1594.05
6 2001-11-8 1566.52 1605.87
7 2001-11-9 1605.07 1630.35
8 2001-11-12 1631.79 1621.19
9 2001-11-13 1609.95 1615.93
10 2001-11-14 1615.75 1617.10
……
共有2493条数据。
接着读入第二份数据:
stock <-read.delim("stock.txt") #注意这里用了不同的数据读入函数
> stock
上市日期招股开始日期
1 2001-11-29 2001-11-6
2 2001-12-62001-11-13
3 2001-12-122001-11-29
4 2001-12-182001-11-22
5 2001-12-20 2001-12-6
6 2001-12-252001-11-29
7 2001-12-262001-12-13
8 2001-12-272001-12-12
9 2002-1-82001-12-19
10 2002-1-112001-12-19
11 2002-1-162001-12-24
12 2002-1-312002-1-16
13 2002-2-52002-1-21
14 2002-2-72002-1-22
……
共有1234条数据。
注意两份数据的长度不一样,而且第一份数据中某些日期的数据缺失了,这给我后面的编程带来了一点小小的麻烦。
第一份数据存在对象dict里,第二份数据存在对象stock里,这两个对象都是数据帧(data frame)类型,即向量的数组。也就是说数据帧里的每个元素是一个向量,如上述两份文件的某一列,而且这些向量的类型可以不同。
开始主程序:
#首先创建一个数值型的向量,保存最后的计算结果
point <- numeric(length(stock$上市日期))
#主循环
for (i in 1:length(stock$上市日期))
{
x<- which(dict$日期 == stock$上市日期[i])
y<- which(dict$日期 == stock$招股开始日期[i])
point[i]<- (dict$收盘[x] - dict$开盘[y]) / dict$开盘[y]
}
令人意外的是,上述程序尽管计算逻辑正确,却并不能正确运行。这是因为length(dict$日期) = 2493,而length(stock$招股开始日期[i]) = 1234。长度不同,R语言提升:错误于Ops.factor(dict$日期, stock$上市日期[i]) : 因子的层次集不同。另一方面,刚刚也有提到,dict里面缺少了一些日期的数据,这导致which(dict$日期 == stock$上市日期[i])函数或which(dict$日期 == stock$招股开始日期[i])函数可能会返回“integer(0)”,从而中断循环,使得后面的计算不能继续。
修改后的程序如下:
for (i in 1:length(stock[,1]))
{
x<- which(as.character(dict[,1]) == as.character(stock[i,1]))
y<- which(as.character(dict[,1]) == as.character(stock[i,2]))
if(length(x) > 0 && length(y) > 0)
point[i]<- (dict[x,3] - dict[y,2]) / dict[y,2]
}
最后,需要把point的结果保存起来,有两种方法:
1.用sink()函数
> sink("point.txt")
> point
> sink()
sink()返回的结果和在控制台上直接输出的格式一样。
2.write.table()函数
write.table(point, "point.cvs", sep="\n",row.names=FALSE, col.names=FALSE)
write.table()函数可以很好地控制输出文件的格式。
最后,当然是把point.cvs中的数据Copy到原来文档里的第10列,也就是浅绿色的那一列。搞定!
|