javaee论坛

普通会员

225648

帖子

340

回复

354

积分

楼主
发表于 2019-10-30 12:56:59 | 查看: 56 | 回复: 1

2、原始数据

   原始文件我已经整理好了,记录了*万科*,*国农科技*,*世纪星源*和*深振业A*这四只股票从2014年一季度到2017年三季度,利润表里“营业总收入”的数据(单位:万元)。每只个股有15条记录,合计60行数据。数据结构如下:

##'data.frame':  60obs.of 3variables:## $季度   :chr "2017-09-30""2017-06-30"...## $名称   :chr "万科""万科""万科""万科"...## $营业总收入:int 1171005069810481858923...

以万科为例,具体内容如下:

data[data$名称=="万科",]## 季度名称营业总收入##1 2017-09-30万科 11710050##2 2017-06-30万科  6981048##3 2017-03-31万科  1858923##4 2016-12-31万科 24047724##5 2016-09-30万科 11705480##6 2016-06-30万科  7479529##7 2016-03-31万科  1461131##8 2015-12-31万科 19554913##9 2015-09-30万科  7959621##102015-06-30万科  5026680##112015-03-31万科  889434##122014-12-31万科 14638800##132014-09-30万科  6313959##142014-06-30万科  4096190##152014-03-31万科  949722我们看到,每只个股按照时间倒序排列,营业总收入是一个累计值。比如,表中显示万科在2017年3季度的营业收入为11710050(万元),2季度的营业收入为6981048(万元),那么万科2017年3季度的营业收入世纪发生额为11710050-6981048=4729002万元。我们的目的是在原始数据的基础之上,再加一列,把单季度的发生额加在后面。

3、处理过程3.1、数据切分

原始数据里有4只股票,他们的数据结构是一致的,处理方法也一致,为了方便处理,把原始数据从数据框切成列表。在dataframe上使用split,可以将dataframe按照指定的条件切成一个个列表。示例如下:

data<-split(data,data$名称) #数据类型class(data)##[1]"list"#列表名称names(data)##[1]"国农科技""深振业A" "世纪星源""万科"#第一个列表内容data[[1]]##     季度  名称营业总收入##162017-09-30国农科技   7100##172017-06-30国农科技   2929##182017-03-31国农科技   1087##192016-12-31国农科技   28767##202016-09-30国农科技   21757##212016-06-30国农科技   10215##222016-03-31国农科技   1348##232015-12-31国农科技   12045##242015-09-30国农科技   8889##252015-06-30国农科技   5955##262015-03-31国农科技   2094##272014-12-31国农科技   8061##282014-09-30国农科技   4842##292014-06-30国农科技   2743##302014-03-31国农科技   1130这样数据从dataframe切分成了4个列表,分别对应每一只个股。

3.2、数据处理

df<-data[[1]]df$季度<-as.Date(df$季度)df<-as.xts(df[-c(1,2)],order.by=df$季度)class(df)##[1]"xts""zoo"df##      营业总收入##2014-03-31   1130##2014-06-30   2743##2014-09-30   4842##2014-12-31   8061##2015-03-31   2094##2015-06-30   5955##2015-09-30   8889##2015-12-31   12045##2016-03-31   1348##2016-06-30   10215##2016-09-30   21757##2016-12-31   28767##2017-03-31   1087##2017-06-30   2929##2017-09-30   7100时间序列只能处理数值型的数据,数据转化成时间序列后,原来数据框中的日期和名称都消失了。要在后面在加上去。现在开始计算单季数据,只要拿当前的值减去上期的值即可。在时间序列了,可以使用DIFF差分函数来实现,diff(x,n),表示将当前值减去N个周期前的值。默认n=1.将处理后的数据合并会原来的数据。并把日期加上去。

datadiff<-diff(df)datanew<-as.data.frame(merge(df,datadiff))datanew<-cbind(row.names(datanew),datanew)colnames(datanew)<-c("季度","营业总收入","营业总收入单季")datanew##季度营业总收入营业总收入单季##2014-03-31   1130      NA##2014-06-30   2743     1613##2014-09-30   4842     2099##2014-12-31   8061     3219##2015-03-31   2094     -5967##2015-06-30   5955     3861##2015-09-30   8889     2934##2015-12-31   12045     3156##2016-03-31   1348    -10697##2016-06-30   10215     8867##2016-09-30   21757     11542##2016-12-31   28767     7010##2017-03-31   1087    -27680##2017-06-30   2929     1842##2017-09-30   7100     4171注意到这个结果还有一个问题,一个是一季度的数据不需要减去上期值,一季度的单季数值等于累计值。所以数据还要处理一下。

#quarter方法来自lubridate包,可以传入文本判断季度datanew[quarter(datanew$季度)==1,3]=datanew[quarter(datanew$季度)==1,2]DataPrc<-function(x){#转成时间序列x$季度<-as.Date(x$季度)StkNam<-as.character(x$名称[1])x<-as.xts(x[-c(1,2)],order.by=x$季度)#利用差分计算单期值并合并x.diff<-diff(x)x.new<-as.data.frame(merge(x,x.diff))x.new<-cbind(row.names(x.new),StkNam,x.new)colnames(x.new)<-c("季度","名称","营业总收入","营业总收入单季")#处理特殊情况#quarter方法来自lubridate包,可以传入文本判断季度x.new[quarter(x.new$季度)==1,4]=x.new[quarter(x.new$季度)==1,3]x.new}stkdata<-lapply(data,DataPrc)stkdata##$国农科技##         季度  名称营业总收入营业总收入单季##2014-03-312014-03-31国农科技   1130     1130##2014-06-302014-06-30国农科技   2743     1613##2014-09-302014-09-30国农科技   4842     2099##2014-12-312014-12-31国农科技   8061     3219##2015-03-312015-03-31国农科技   2094     2094##2015-06-302015-06-30国农科技   5955     3861##2015-09-302015-09-30国农科技   8889     2934##2015-12-312015-12-31国农科技   12045     3156##2016-03-312016-03-31国农科技   1348     1348##2016-06-302016-06-30国农科技   10215     8867##2016-09-302016-09-30国农科技   21757     11542##2016-12-312016-12-31国农科技   28767     7010##2017-03-312017-03-31国农科技   1087     1087##2017-06-302017-06-30国农科技   2929     1842##2017-09-302017-09-30国农科技   7100     4171##$深振业A##         季度  名称营业总收入营业总收入单季##2014-03-312014-03-31深振业A   26292     26292##2014-06-302014-06-30深振业A   49149     22857##2014-09-302014-09-30深振业A   64985     15836##2014-12-312014-12-31深振业A  232873    167888##2015-03-312015-03-31深振业A  138923    138923##2015-06-302015-06-30深振业A  202261     63338##2015-09-302015-09-30深振业A  230546     28285##2015-12-312015-12-31深振业A  365431    134885##2016-03-312016-03-31深振业A   38249     38249##2016-06-302016-06-30深振业A   86869     48620##2016-09-302016-09-30深振业A  114571     27702##2016-12-312016-12-31深振业A  335883    221312##2017-03-312017-03-31深振业A  116791    116791##2017-06-302017-06-30深振业A  186960     70169##2017-09-302017-09-30深振业A  231926     44966####$世纪星源##         季度  名称营业总收入营业总收入单季##2014-03-312014-03-31世纪星源   1218     1218##2014-06-302014-06-30世纪星源   2386     1168##2014-09-302014-09-30世纪星源   3585     1199##2014-12-312014-12-31世纪星源   5278     1693##2015-03-312015-03-31世纪星源   1349     1349##2015-06-302015-06-30世纪星源   3629     2280##2015-09-302015-09-30世纪星源   4576      947##2015-12-312015-12-31世纪星源   8413     3837##2016-03-312016-03-31世纪星源   4342     4342##2016-06-302016-06-30世纪星源   18995     14653##2016-09-302016-09-30世纪星源   35050     16055##2016-12-312016-12-31世纪星源   48186     13136##2017-03-312017-03-31世纪星源   7145     7145##2017-06-302017-06-30世纪星源   20360     13215##2017-09-302017-09-30世纪星源   31423     11063##$万科##         季度名称营业总收入营业总收入单季##2014-03-312014-03-31万科  949722    949722##2014-06-302014-06-30万科  4096190    3146468##2014-09-302014-09-30万科  6313959    2217769##2014-12-312014-12-31万科 14638800    8324841##2015-03-312015-03-31万科  889434    889434##2015-06-302015-06-30万科  5026680    4137246##2015-09-302015-09-30万科  7959621    2932941##2015-12-312015-12-31万科 19554913   11595292##2016-03-312016-03-31万科  1461131    1461131##2016-06-302016-06-30万科  7479529    6018398##2016-09-302016-09-30万科 11705480    4225951##2016-12-312016-12-31万科 24047724   12342244##2017-03-312017-03-31万科  1858923    1858923##2017-06-302017-06-30万科  6981048    5122125##2017-09-302017-09-30万科 11710050    47290024、合并

以上结果显示数据都是列表,把它们合成一个数据框。方便后续处理。你当然可以选择使用循环将列表合并,但R里处理循环的效率实在无法恭维。这里有个更好的办法,代码如下:

result<-do.call(rbind,stkdata)rownames(result)<-NULLhead(result[result$名称=="世纪星源",],2)#季度  名称营业总收入营业总收入单季##2014-03-31世纪星源  1218  1218##2014-06-30世纪星源  2386  1168do.call()是告诉列表一个函数,让列表里的所有元素来执行这个函数。将其用于列表合并,效果比循环好太多。

这样,我们就把数据整理完毕了。这种差分的数据处理方法,在很多场景都有应用。比如运营上拿到了一系列周期上的指标数值,都同时会看看同比、环比的增减情况。这些数据使用传统的数据结构,使用传统的数据处理方法,计算脚本都是很复杂的,而把数据转化成时间序列后,这些处理的过程都可以用简单的方法解决。另外,在使用R进行数据分析时,应该利用这种向量化语言的特点,用向量化的方法处理数据。


普通会员

0

帖子

311

回复

320

积分
沙发
发表于 2024-04-19 00:25:57

很好

您需要登录后才可以回帖 登录 | 立即注册

触屏版| 电脑版

技术支持 历史网 V2.0 © 2016-2017