作者:蓝京,商业银行数据分析师


1、 本文简介

本文以处理A股财务报表为例,介绍了将数据转换成时间序列后在进行处理的一些方法和思路。将会用到xts,lapply,do.call等数据结构和函数。

我们从各个途径获得了个股的财务报表原始数据后,还需要对数据做一些处理,以便后续指标计算和使用。举个简单的例子,个股发布的利润表和现金流量表,在年内各个季度值都是累计值,不方便环比比较,所以我们现在想把它们全部都处理成当季实际发生额。对于这样的数据,无论是SQL还是R,Python里面传统的数据结构,实现起来都是要费一番功夫进行数据处理的。但是如果使用了时间序列的方法,再结合一些R语言自带的语法结构,只需要短短几行代码,就能完成复杂的数据清洗。

2、 原始数据

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

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

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

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## 10 2015-06-30 万科    5026680## 11 2015-03-31 万科     889434## 12 2014-12-31 万科   14638800## 13 2014-09-30 万科    6313959## 14 2014-06-30 万科    4096190## 15 2014-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]]
##          季度     名称 营业总收入## 16 2017-09-30 国农科技       7100## 17 2017-06-30 国农科技       2929## 18 2017-03-31 国农科技       1087## 19 2016-12-31 国农科技      28767## 20 2016-09-30 国农科技      21757## 21 2016-06-30 国农科技      10215## 22 2016-03-31 国农科技       1348## 23 2015-12-31 国农科技      12045## 24 2015-09-30 国农科技       8889## 25 2015-06-30 国农科技       5955## 26 2015-03-31 国农科技       2094## 27 2014-12-31 国农科技       8061## 28 2014-09-30 国农科技       4842## 29 2014-06-30 国农科技       2743## 30 2014-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-31 2014-03-31 国农科技       1130           1130## 2014-06-30 2014-06-30 国农科技       2743           1613## 2014-09-30 2014-09-30 国农科技       4842           2099## 2014-12-31 2014-12-31 国农科技       8061           3219## 2015-03-31 2015-03-31 国农科技       2094           2094## 2015-06-30 2015-06-30 国农科技       5955           3861## 2015-09-30 2015-09-30 国农科技       8889           2934## 2015-12-31 2015-12-31 国农科技      12045           3156## 2016-03-31 2016-03-31 国农科技       1348           1348## 2016-06-30 2016-06-30 国农科技      10215           8867## 2016-09-30 2016-09-30 国农科技      21757          11542## 2016-12-31 2016-12-31 国农科技      28767           7010## 2017-03-31 2017-03-31 国农科技       1087           1087## 2017-06-30 2017-06-30 国农科技       2929           1842## 2017-09-30 2017-09-30 国农科技       7100           4171

## $深振业A##                  季度    名称 营业总收入 营业总收入单季## 2014-03-31 2014-03-31 深振业A      26292          26292## 2014-06-30 2014-06-30 深振业A      49149          22857## 2014-09-30 2014-09-30 深振业A      64985          15836## 2014-12-31 2014-12-31 深振业A     232873         167888## 2015-03-31 2015-03-31 深振业A     138923         138923## 2015-06-30 2015-06-30 深振业A     202261          63338## 2015-09-30 2015-09-30 深振业A     230546          28285## 2015-12-31 2015-12-31 深振业A     365431         134885## 2016-03-31 2016-03-31 深振业A      38249          38249## 2016-06-30 2016-06-30 深振业A      86869          48620## 2016-09-30 2016-09-30 深振业A     114571          27702## 2016-12-31 2016-12-31 深振业A     335883         221312## 2017-03-31 2017-03-31 深振业A     116791         116791## 2017-06-30 2017-06-30 深振业A     186960          70169## 2017-09-30 2017-09-30 深振业A     231926          44966 

 ## ## $世纪星源##                  季度     名称 营业总收入 营业总收入单季## 2014-03-31 2014-03-31 世纪星源       1218           1218## 2014-06-30 2014-06-30 世纪星源       2386           1168## 2014-09-30 2014-09-30 世纪星源       3585           1199## 2014-12-31 2014-12-31 世纪星源       5278           1693## 2015-03-31 2015-03-31 世纪星源       1349           1349## 2015-06-30 2015-06-30 世纪星源       3629           2280## 2015-09-30 2015-09-30 世纪星源       4576            947## 2015-12-31 2015-12-31 世纪星源       8413           3837## 2016-03-31 2016-03-31 世纪星源       4342           4342## 2016-06-30 2016-06-30 世纪星源      18995          14653## 2016-09-30 2016-09-30 世纪星源      35050          16055## 2016-12-31 2016-12-31 世纪星源      48186          13136## 2017-03-31 2017-03-31 世纪星源       7145           7145## 2017-06-30 2017-06-30 世纪星源      20360          13215## 2017-09-30 2017-09-30 世纪星源      31423          11063

 ## $万科##                  季度 名称 营业总收入 营业总收入单季## 2014-03-31 2014-03-31 万科     949722         949722## 2014-06-30 2014-06-30 万科    4096190        3146468## 2014-09-30 2014-09-30 万科    6313959        2217769## 2014-12-31 2014-12-31 万科   14638800        8324841## 2015-03-31 2015-03-31 万科     889434         889434## 2015-06-30 2015-06-30 万科    5026680        4137246## 2015-09-30 2015-09-30 万科    7959621        2932941## 2015-12-31 2015-12-31 万科   19554913       11595292## 2016-03-31 2016-03-31 万科    1461131        1461131## 2016-06-30 2016-06-30 万科    7479529        6018398## 2016-09-30 2016-09-30 万科   11705480        4225951## 2016-12-31 2016-12-31 万科   24047724       12342244## 2017-03-31 2017-03-31 万科    1858923        1858923## 2017-06-30 2017-06-30 万科    6981048        5122125## 2017-09-30 2017-09-30 万科   11710050        4729002

4、合并

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

result<- do.call(rbind,stkdata)
rownames(result) <- NULL
head(result[result$名称=="世纪星源",],2)# 季度     名称 营业总收入 营业总收入单季## 2014-03-31 世纪星源     1218    1218## 2014-06-30 世纪星源     2386    1168

do.call() 是告诉列表一个函数,让列表里的所有元素来执行这个函数。将其用于列表合并,效果比循环好太多。

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

用时间序列的方法处理数据相关推荐

  1. 时间序列预测方法汇总:从理论到实践(附Kaggle经典比赛方案)

    ©作者 | Light 学校 | 中国科学院大学 研究方向 | 机器学习 时间序列是我最喜欢研究的一种问题,这里我列一下时间序列最常用的方法,包括理论和实践两部分.理论部分大多是各路神仙原创的高赞解读 ...

  2. python pandas 日期_python+pandas+时间、日期以及时间序列处理方法

    python+pandas+时间.日期以及时间序列处理方法 先简单的了解下日期和时间数据类型及工具 python标准库包含于日期(date)和时间(time)数据的数据类型,datetime.time ...

  3. 时间序列预测方法最全总结!

    时间序列预测就是利用过去一段时间的数据来预测未来一段时间内的信息,包括连续型预测(数值预测,范围估计)与离散型预测(事件预测)等,具有非常高的商业价值. 需要明确一点的是,与回归分析预测模型不同,时间 ...

  4. 时间序列预测方法及多步预测方法汇总

    本文转载自 https://zhuanlan.zhihu.com/p/471014006 时间序列多步预测方法 https://zhuanlan.zhihu.com/p/390093091 时间序列预 ...

  5. 时间序列预测方法_让我们使用经典方法预测您的时间序列

    时间序列预测方法 时间序列预测 (Time Series Forecasting) 背景 (Background) We learned various data preparation techni ...

  6. 时间序列的数据分析(七):数据平稳性

    之前已经完成了六篇关于时间序列的博客,还没有阅读过的读者请先阅读: 时间序列的数据分析(一):主要成分 时间序列的数据分析(二):数据趋势的计算 时间序列的数据分析(三):经典时间序列分解 时间序列的 ...

  7. 11种典型的时间序列回归预测方法大集合——附代码

    目录 摘要: 下图程序内操作手册部分展示: 下图程序运行后出图部分展示: 本文Matlab工具箱与源代码: 摘要: 时间序列预测就是利用过去一段时间的数据来预测未来一段时间内的信息,包括连续型预测(数 ...

  8. python pandas 日期格式_python+pandas+时间、日期以及时间序列处理方法

    先简单的了解下日期和时间数据类型及工具 python标准库包含于日期(date)和时间(time)数据的数据类型,datetime.time以及calendar模块会被经常用到. datetime以毫 ...

  9. 机器学习 11 种经典时间序列预测方法

    文章目录 一.时间序列预测方法 二.用法讲解及python程序 1.AR 2.MA 3.ARMA 4.ARIMA 5.SARIMA 6.SARIMAX 7.VAR 8.VARMA 9.VARMAX 1 ...

  10. 【时间序列】时间序列预测方法总结(对应文章给出详细链接)

    来自 | 知乎 作者 | BINGO Hong 链接 | https://zhuanlan.zhihu.com/p/67832773 已经得到作者授权,仅作学术交流,请勿二次转载 1. 时间序列基本规 ...

最新文章

  1. 阮一峰老师的ES6入门:async 函数
  2. 【每日一算法】买卖股票的最佳时机
  3. SAP LSMW 物料主数据导入毛重净重放大1000倍问题之对策
  4. linux shell 脚本攻略学习10--生成任意大小的文件和文本文件的交集与差集详解
  5. 王者争雄服务器维护,王者争雄_王者争雄官网_攻略-第一手游网
  6. 浅析网站建设必要的专用软件
  7. WebApiClient的接口输入验证
  8. java异常处理试题答案_java试题及答案
  9. ASP.NET初级传智播客.net第十季asp.net基础 文字总结(未完)
  10. vue监听用户在页面的浏览时间需在beforeDestroy()里面进行销毁
  11. GitHub增加了代码审查、项目管理等新功能
  12. One Switch 让你的 Mac 也能拥有控制中心
  13. Java 开发流程、运行原理、JVM 规范与实现
  14. Linux的vim编辑器常用命令
  15. 【数学建模】CUMCM-2016A 系泊系统的设计 解题思路整理
  16. 职场:迈过职业生涯中的5个坎
  17. pytorch gpu版本安装
  18. 第一章之OpenCV安装
  19. 雷柏MT750w鼠标无线蓝牙连接教程
  20. vivo手机显示服务器维修中,OPPO和vivo手机通病进水后黑屏不显示怎么维修

热门文章

  1. 令人笑喷的56个代码注释,最后几个老衲实在憋不住了。。。
  2. 横空出世,比Visio快10倍的画图工具来了
  3. 牛逼!Intellij IDEA竟然有个功能可自动生成代码,你用过没?
  4. 如何写一手好 SQL!!!
  5. 执行力,才是拉开人与人差距的关键
  6. 说说微信聊天记录收费这件事
  7. 特殊时期,找工作的 9 点建议!
  8. 别轻易接受父母的建议
  9. 校门外的树和memset
  10. Struts2——一个用来开发 MVC 应用程序的框架