Blog Archives

用R语言解读凯利公式

用IT技术玩金融系列文章,将介绍如何使用IT技术,处理金融大数据。在互联网混迹多年,已经熟练掌握一些IT技术。单纯地在互联网做开发,总觉得使劲的方式不对。要想靠技术养活自己,就要把技术变现。通过“跨界”可以寻找新的机会,创造技术的壁垒。

金融是离钱最近的市场,也是变现的好渠道!今天就开始踏上“用IT技术玩金融”之旅!

关于作者:

  • 张丹(Conan), 程序员R,Nodejs,Java
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/finance-kelly

前言

职业做投机交易的人,应该都听说过凯利公式,这是一个通过计算胜率和赔率,来选择最佳投注比例的公式,目的是长期获得最高的盈利。

只要找到长期看必胜的局,接下来就是让时间帮我们赚钱了。

目录

  1. 开始赌局
  2. 凯利公式
  3. 赌局的最优解
  4. 让时间帮我们赚钱

1. 开始赌局

设游戏赌局,你赢的概率是80%,输的概率是20%,赢时的净收益率是100%,输时的亏损率也是100%。如果赢,你每赌1元可以赢得1元;如果输,则每赌1元将会输掉1元。赌局可以进行无限次,每次下的赌注可由你自己任意定。如果你的初始资金是100元,那么怎么样下注,才能使得长期收益最大?

对于胜率80%,从感觉上应该是很有把握的事情了。那么我们先主观判断一次,用90%的仓位去赌一下,看看结果怎么呢?如果下注10次,按80%胜率,8次胜,2次负。我们来算一下最后的结果。


# 设置胜负,1胜,0负
> win<-c(1,1,1,0,1,1,0,1,1,1)
 
# 分别按投注计算每回合的剩余资金 
> a1<-(1+0.9)*100
> a2<-a1*(1+0.9)
> a3<-a2*(1+0.9)
> a4<-a3*0.1
> a5<-a4*(1+0.9)
> a6<-a5*(1+0.9)
> a7<-a6*0.1
> a8<-a7*(1+0.9)
> a9<-a8*(1+0.9)
> a10<-a9*(1+0.9)
 
> dat<-c(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
> df<-data.frame(win,dat)

# 打印剩余资金列表
> df
   win      dat
1    1 190.0000
2    1 361.0000
3    1 685.9000
4    0  68.5900
5    1 130.3210
6    1 247.6099
7    0  24.7610
8    1  47.0459
9    1  89.3872
10   1 169.8356

10次交易后,赢了8次,只输了2次,我们从100元本金,上升到了169元,收益率为69%,还是不错的。最高的时候,资金为685元,收益率为685%,赚了6倍多。最低则是只剩下24元,真是赔的好惨啊!

接下来,画出资金曲线。这是一个过山车式的曲线,赚钱的时候非常猛,一旦赌输了,就产生了巨大的亏损。


# 画出资金曲线 
> plot(df$dat,type='l')

曲线很陡峭,波动很大,回撤也很大,完全就是在赌博。

怎么样才能让资金曲线好看一些呢?如果每次下注用少一点资金,是不是会更好呢?那么我继续试一下。分别计算每次下注资金为 60%,40%,20%,10%的4个维度的仓位的情况。


> library(magrittr)

# 定义现金流量函数:win=胜负结果,b=赔率,pos=仓位
> postion<-function(win,b=1,pos=0.6){            # 省略代码
+ }
 
# 设置胜负,1胜,0负
> win<-c(1,1,1,0,1,1,0,1,1,1) 
> prob<-0.8                      # 胜率
> n<-10                          # 赌局数
> b<-1                           # 赔率
> caption<-100                   # 金额
 
# 分别计算不同仓位的剩余现金
> pos90<-postion(win,b,0.9)*caption
> pos60<-postion(win,b,0.6)*caption
> pos40<-postion(win,b,0.4)*caption
> pos20<-postion(win,b,0.2)*caption
> pos10<-postion(win,b,0.1)*caption

# 合并到数据框
> df1<-data.frame(win,pos90,pos60,pos40,pos20,pos10)

# 打印计算结果
> df1
   win    pos90   pos60   pos40   pos20   pos10
1    1 190.0000 160.000 140.000 120.000 110.000
2    1 361.0000 256.000 196.000 144.000 121.000
3    1 685.9000 409.600 274.400 172.800 133.100
4    0  68.5900 163.840 164.640 138.240 119.790
5    1 130.3210 262.144 230.496 165.888 131.769
6    1 247.6099 419.430 322.694 199.066 144.946
7    0  24.7610 167.772 193.617 159.252 130.451
8    1  47.0459 268.435 271.063 191.103 143.496
9    1  89.3872 429.497 379.489 229.324 157.846
10   1 169.8356 687.195 531.284 275.188 173.631

我们看到,只是简单地调整了交易的仓位比例,那么交易10次后,你剩余的现是就是有很大的不同的。其中pos60列,即60%仓位的交易,获得的回报最高为687元,而90%的仓位获得的回报,是这里面最少的。而且非常有意思的是,后面的4种仓位设置,每次交易后的资金都大于100元的原始本金。

画出资金曲线


> library(ggplot2)
> library(scales)
> library(reshape2)

# 数据转型 
> df1$num<-1:nrow(df1)
> df<-melt(df1[,-1],id.vars="num")
 
# 画图 
> g<-ggplot(df,aes(x=num,y=value,colour=variable ))
> g<-g+geom_line()
> g

从图中可以看到,对于高胜率的情况,大的仓位是可以有高回报的,但是风险也大;小仓位是相对平稳的增长。

2. 凯利公式

那么多少的仓位是最优的呢?接下来的问题,就是凯利公式会告诉我们的。

在概率论中,凯利公式(The Kelly Criterion)是一个用以使特定赌局中,拥有正期望值之重复行为长期增长率最大化的公式,由约翰·拉里·凯利于1956年在《贝尔系统技术期刊》中发表,可用以计算出每次游戏中应投注的资金比例。

除可将长期增长率最大化外,此公式不会在任何赌局中,有失去全部现有资金的可能,因此有不存在破产疑虑的优点。公式中,假设货币与赌局可无限分割,只要资金足够多,长期一定是会赚到钱的。

凯利公式的最一般性陈述为,寻找能最大化结果对数期望值的资本比例f,即可获得长期增长率的最大化。对于只有两种结果的简单赌局而言,即 输失去所有本金,胜获得资金乘以特定的赔率。

可以用下面公式来表示:

其中

  • f* 投注的比例
  • b 赔率,盈亏比,即平均一次盈利与一次亏损两者的比例
  • p 胜率
  • q 败率,即 1 – p

用凯利公式对上面的例子进行测试,胜率p=0.8,失败率q=1-p=0.2,赔率b=1,失败则下注资金完全损失,计算下注比例为


f* = (b*p-q)/b = (1*0.8-0.2)/1=0.6

所以,赌客应在每次机会中下注现有资金的60%,可以获得最大化资金的长期增长率。

通过数学变型,可以很容易得到凯利公式的另一种表达式


Kelly % = W – [(1 – W) / R]

其中Kelly % 就是上式中的f*,W就是p胜率,R就是b赔率。两者看似不同,其实完全等效一致。

对于上面的例子,我们可以计算


Kelly % = W – [(1 – W) / R] = 0.8-[(1-0.8)/1] = 0.6 

凯利公式,有一个优化的变型。如果每次下注失败后,不是全部亏损,只是亏损部分,我们对上面公式可以做一个优化,增加亏损比例参数c,公式改写为下面格式


f* =  (b*p-c*q)/c*b

其中

  • f* 投注的比例
  • b 赔率,盈亏比,即平均一次盈利与一次亏损两者的比例
  • p 胜率
  • q 败率,即 1 – p
  • c 亏损比例

对于上面的例子,如果每次亏损是c=0.8,其他条件不变,那么我们应该用什么仓位进行交易呢?


f* = (b*p-q)/b = (1*0.8-0.8*0.2)/(0.8*1)=0.8

通过计算结果是0.8,我可以增大仓位。

凯利公式定义了长期获得最高的盈利的仓位确认的计算方法,我们自己也可以按照凯利公式的数学定义,进行推到一下。

假设一个赌局,每投资1,有p的概率可获得额外正收益W,有q=1-p的概率可获得额外的负收益-L,每次投资比例为x,建立收益为f(x)的目标函数,使得期望收益最大化。

转化为规划问题:

从推到可看出,标准的凯利公式只是当L=1的情况是一个应用,通过优化可增加了亏损比例参数。

3. 赌局的最优解

我们已经把公式介绍的很清楚了,那么接下来,就可以用程序实现进行实现了。


# 凯利公式,实现函数
> kelly<-function(prob,b=1,loss=1){   # 省略代码
+ }

用凯利公式计算的上文中的例子。


> prob<-0.8                     # 胜率
> b<-1                          # 赔率
> k<-kelly(prob,b,1);k
[1] 0.6

这时通过凯利公式,我们就能算出最最优的解其实是0.6的仓位设置,也就可以解释,上面的结果60%的仓位占比,获得的收益是最大的。

接下来,我们再比较一下不同的胜率和赔率的最优解是什么?

大胜率和大赔率时,可以重仓。当80%的胜率,2倍赔率时,仓位为70%。


> kelly(0.8,2)
[1] 0.7

通常情况下的赌局,不足50%的胜率,高赔率时,可以轻仓。当45%的胜率,2倍赔率时,仓位为17.5%。


> kelly(0.45,2)
[1] 0.175

通常情况下的赌局,不足50%的胜率,低赔率时,不要参考。当45%的胜率,1倍赔率时,不参与赌局。


> kelly(0.45,1)
[1] "Lost!!!"
[1] 0

小胜率,中等赔率时,不要参与。


> kelly(0.2,1)
[1] "Lost!!!"
[1] 0

小胜率,中等赔率时,中等损失,不要参与。


> kelly(0.2,1,0.5)
[1] "Lost!!!"
[1] 0

小胜率,中等赔率时,很小损失,可以All in。很小的损失比例,其实是变相的增大了赔率。


> kelly(0.2,1,0.1)
[1] "All In"
[1] 1

大胜率,很小赔率,很小损失,All in。


> kelly(0.8,0.1,0.1)
[1] "All In"
[1] 1

中胜率,很小赔率,很小损失,不要参与。


> kelly(0.45,0.1,0.1)
[1] "Lost!!!"
[1] 0

总结一下,投机操作的游戏规则。

胜率 赔率 损失率 仓位 指导建议 备注
80% 2 100% 70% 重仓 大胜率、大赔率、全部损失
45% 2 100% 17.5% 轻仓 中胜率、大赔率、全部损失
45% 1 100% 0 离场 中胜率、中赔率、全部损失
20% 1 100% 0 离场 小胜率、中赔率、全部损失
20% 1 50% 0 离场 小胜率、中赔率、中等损失
20% 1 10% 100% 满仓 小胜率、中赔率、小损失
80% 10% 10% 100% 满仓 大胜率、小赔率、小损失
45% 10% 10% 0 离场 中胜率、小赔率、小损失

这样我们就判断出,哪些投机操作值得玩,哪些不能玩,应该怎么玩。是不是很神奇!!

4. 让时间帮我们赚钱

根据凯利公式的定义,赌局可以进行无限次,那么当真的把赌局设置为很大时,会是什么情况呢?

我们把第一次的数据,进行100次的赌局,胜率为80%,赔率为1,金额100元,看一下结果。


> n<-100                          # 赌局数
> prob<-0.8                       # 胜率
> b<-1                            # 赔率
> caption<-100                    # 金额

# 基本二项分布,生成每盘的赌局正负
> set.seed(1)
> win<-rbinom(n,1,prob)
 
# 生成每盘的资金
> pos90<-postion(win,b,0.9)*caption   # 90%仓位
> pos60<-postion(win,b,0.6)*caption   # 60%仓位
> pos40<-postion(win,b,0.4)*caption   # 40%仓位
> pos20<-postion(win,b,0.2)*caption   # 20%仓位
> pos10<-postion(win,b,0.1)*caption   # 10%仓位

# 打印数据
> df2<-data.frame(win,pos90,pos60,pos40,pos20,pos10)
> tail(df2)
    win     pos90       pos60       pos40   pos20   pos10
95    1 105083487 5.73375e+11  9874948167 5067085 34506.6
96    1 199658625 9.17399e+11 13824927434 6080503 37957.3
97    1 379351388 1.46784e+12 19354898407 7296603 41753.0
98    1 720767637 2.34854e+12 27096857770 8755924 45928.3
99    0  72076764 9.39417e+11 16258114662 7004739 41335.5
100   1 136945851 1.50307e+12 22761360527 8405687 45469.0

从100盘赌局后的结果来看,60%的仓位可以获得最高收益的,为1.50307e+12,比其他的仓位都要高少非常。

接下来,我们生成资金曲线图。


# 数据转型
> df2$num<-1:nrow(df2)
> df<-melt(df2[,-1],id.vars = "num")

# 画图 
> g<-ggplot(df,aes(x=num,y=value,colour=variable ))
> g<-g+geom_line()
> g<-g+scale_y_log10()  # y坐标轴log化
> g

资金曲线图能非常直观地告诉了我们,什么的仓位有什么样曲线形状。你如果追求低风险,就用10%仓位稳健上涨。90%接近满仓并不是最赚钱的,反而是60%的仓位是有最大的回报。

我们再用凯利公式进行计算,可以发现结果最优的结果也是60%。


> kelly(prob,1)
[1] 0.6

神奇的算法,可以有效的帮我们控制仓位,最大化长期收益。只要找到长期必胜的局,接下来就是让时间帮我们赚钱了。下一篇文章,将介绍凯利公式在金融市场应用的应用。

写文章很辛苦,如果需要获得本文源代码或加入量化投资社群,请扫下面二维码,请作者喝杯咖啡。

转载请注明出处:
http://blog.fens.me/finance-kelly

打赏作者

2017WOT全球软件开发技术峰会:面向数据的思维模式和R语言编程

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹, 程序员R,Nodejs,Java
  • weibo:@Conan_Z
  • blog:http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-wot-20171202

前言

第三次参加WOT的峰会了,这次来到深圳进行分享,蓝蓝的天空,暖暖的天气,真是宜居的城市。

在本次大会上,我主要介绍的是面向数据的思维模式和R语言的编程技巧。谈到思维模式,就是一种自我进化的方法,当你在一味的追求技术的过程中,积累了很多年,遇到了突破不了的瓶颈。你就需要停下来,想一想,是不是要换个角度看问题。

目录

  1. 我的演讲主题:面向数据的思维模式和R语言编程
  2. 会议体验和照片分享

1. 我的演讲主题:面向数据的思维模式和R语言编程

首先,感谢51cto主办方的邀请,并且让我担当“编程语言与框架”分会场的出品人。我本次分享的主题为:面向数据的思维模式和R语言编程,PPT下载,主要内容来自我的2篇文篇:用R语言把数据玩出花样 和 51CTO采访稿 如何用R语言打开面向数据的思维模式

分享主题的目录大纲如下:

  1. 面向数据的思维模式
  2. 金融理论
  3. R语言进行数据处理

本此分析主要是从数据的角度切入,比较程序员思维与数据分析师思维的差异,以及思考方式的区别。在数据已经积累有一定数据量后,怎么让数据产生价值,如何设计数据产品,就是一个非常值得我们思考的问题。数据,不仅仅只存在于互联网行业,数据存在于各行各业。一旦用数据的思维去思考,你就能够发现,无数的机会在等着你。

我主要是研究量化投资,直白一点说,就是对金融数据进行分析,建立数据模型,找到赚钱的机会。同时,我也在致力于推动R语言在中国金融领域的发展,让R可以给更多的用户使用,培养出更多的数据分析师。也希望让我们中国人的技术能够走出去到世界的舞台。希望多能认识志同道合的朋友,一起做一些事情。

2. 会议体验和照片分享

会议的主页:http://wot.51cto.com/act/2017/development/

本次wot的大会,由9个分会场组成,我是在编程语言与框架会场。本会场的主题是,更多新兴的编程语言、框架和工具改变着开发者的工作方式,并带来更多的可能。如何在日新月异的潮流下理智地选择编程语言,确保框架的稳健和成熟?本专场将分享来自最值得关注的语言和框架的最佳实践。

我的介绍和照片分享。

2.2 会议相关照片

本次的场地在 在深圳中洲万豪酒店,五星级,市中心,高楼大厦林立,会场气派。

这是我,专业照相就是帅。

还是我,签名赠书。

签名赠书。

与谢佳标老师,互赚新书。

大会现场的同学们,1000+人次。

蓝天,白云,大高楼

晚宴,英雄会。

主办方的小伙伴辛苦啦!!获得嘉宾和听众的一致好评!

转载请注明出处:
http://blog.fens.me/meeting-wot-20171202

打赏作者

图书出版《R的极客理想-量化投资篇》

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-book3/

前言

终于等到R的极客理想系列,第三本《R的极客理想-量化投资篇》一书出版了。写书不仅是一个漫长的过程,更是知识的浓缩和再精华的过程;写书不仅把自己会的东西记录下来,还要站在读者的角度,让其他人也能看得懂;写书不同于写博客,不仅要保证超过5遍以上的审阅,还要遵守出版的各种规则,包括格式、文字、目录、图片,公式,代码,引用….

写书不是一件容易的事情,这是R的极客理想系列最后一本图书。希望更多的朋友都能静心下来,写本自己的书。尊重知识,就是尊重你的未来。

目录

  1. 写书体验
  2. 为什么要写这本书
  3. 读者对象
  4. 如何阅读本书
  5. 致谢

1. 写书体验

本书是我写的“R的极客理想”系列丛书的第三本,是R语言与金融量化投资领域结合的一本书,本书的主要写作目标就是把R语言的技术和实际的金融量化案例结合起来,让读者能切身的体会把知识变成真正的生产力。

本书撰写花了很长的时间才得以完成,因本书涉猎广泛,包括了大量地跨学科的知识,用通俗易懂的语言描述出来,并让读者更容易地理解并非易事,以致于我自己在写作过程中,有过数次想放弃的冲动。这本书最终完成,都源于每次看到读者在我博客中的留言,看到大家的对于知识的期待和对于我本人的鼓励,这些都是我把这项艰苦的事业完成,源源不断的动力和鞭策。有的同学开玩笑地留言说,“集齐全套图书,就可以召唤神龙了”。我真的非常感谢读者,对于图书的高度肯定和对我不断的支持。

在本书的写作过程中,我经历了一次创业的洗礼,体验了人生的大起和大落,这段特殊的经历也让我有了新目标和方向。每当我回忆整个的创业过程,都觉得自己太年轻了。光有满腔的热情和技术,只能让我把事情做起来,但是经验和阅历的不足,不能支撑我成为一个成功的创业者。天时,地利,人和,缺一不可。

图书介绍的网站http://fens.me/book,介绍了本书的基本情况,包括序、前方、目录、勘误、代码、试读、封面、交流等几个方面内容,读者有任何问题,都可以在网站中留言,并得到我的回复。同时,可以加QQ群:383275651,和更多的网友进行交流。网站还有视频专区(http://fens.me/video),提供我录制的各种视频课程,包括 R, Nodejs, Hadoop, 金融量化投资 等,视频收入仅用于网站的运营成本。

前两本上市后不仅再国内取得了不俗的成绩,获得了良好的口碑,而且英文版被美国知名的出版集团CRC引进,在北美市场也获得了读者的热捧,本书的英文版和繁体版随后也会在美国和中国台湾发行。

最后附上购买链接,各大网站都能买到,建议先去比比价:互动出版社京东当当亚马逊

当然,如果你需要一本签名的书,可以联系我订购,但是成本有点高,图书原价+货到付款;也可以带着书,到各种我参加的分享会来找我,我每年有不少的分享活动

2. 为什么要写这本书

本书撰写的一个主要思路是从IT人的角度,通过技术来切入金融市场,进行量化投资。发挥IT人的专注学习、乐于分享的精神,借助互联网快速传播知识,打破传统的金融壁垒。发挥“极客”的创造力,让知识变成生产力,让更多的有理想的IT人,能够有机会进入金融行业,推动金融行业的改革和创新。

但这不是一本简单易懂的书,因为量化投资是跨学科的领域。你需要有多学科的知识储备,才能胜任量化投资的工作。而本书所涉及的相关的内容,可能需要多本书籍的相关知识支撑才能描述完成。

阅读本书,不但需要你有R语言的使用经验,更需要有对金融市场知识的理解。本书主要介绍了三部分内容,涵盖金融市场,统计知识和IT技术。

  • 金融市场,包括了中国的金融二级市场环境的介绍、交易工具的使用、金融产品的交易规则、国内机构投研思路、策略和回测、基金会计等金融行业的基础知识。
  • 统计知识,包括了时间序列、一元线性回归、多元线性回归、自回归等统计和计量的模型算法。
  • IT技术,就是R语言相关的编程技术,金融量化程序包的使用,金融数据处理,金融数据模型的构建,量化策略的实现思路,R语言代码的编写等。

同时,本书使用了很多的真实案例,以中国实际的金融市场为背景,你会感觉到市场所带来的波动,国家宏观政策对于市场的影响,散户思维与专业投资者的差异,量化思路与主观思路对于市场的不同理解。

本书是我在实际投资研究中的总结,从金融理论模型,到市场特征检验,再到数学公式,R语言建模,再到历史数据回测,会计资产核算,最后进行实盘交易。通过R语言,可以很简单地实现我们脑子中的一个投资想法。类似的投资想法其实谁都有,利用IT人的技术优势,可以真正地与实际操作结合起来。

本书所涉及的金融产品,包括了股票、期货、债券、基金、现金管理等,跨越多个金融市场多种金融标的物。交易模型和交易策略,有基于市场技术指标的量价策略,有基于统计理论的套利策略,有基于金融产品规则的事件性策略;有针对全市场扫描的选股策略,也有高频交易的择时策略。相信本书,会另你感受到金融市场的魅力,以及技术优势能给我们带来的价值。

要想深入理解本书的每一篇的内容,可能你需要像我一样,不仅有技术的积累,还要真正地去金融市场做做交易,多和行业内的人进行沟通,不断地学习和思考。

让IT技术,提高金融的效率。

传统的交易员,都是凭借多年的交易训练,人工的每日盯盘,观察市场的变化。一个好的交易员,可以同时观测几个金融市场的几十个交易品种。随着金融产品的发展,股票市场已经达到3000多只股票,债券市场达到3000多只债券,公墓基金市场达到了6000多只基金,还有多种的金融衍生品,大量金融产品的发展,已经不是能依靠个人之力去消化和分析了。

通过计算机在全市场进行扫面,发现不合理的定价和交易机会,可以极大的提高交易员效率。一种理想化的设计,让程序来为我们交易赚钱,我们就可以去做自己喜欢的事情了。让技术变现,解放我们的生活。

本书中的原创观点和方法,都是基于理论研究在实践中的经验所得。实际上,长久以来我也在找这样的一本书,能够把书本上的理论模型与实际业务相结合,但并没有找到,或者并没有符合中国市场的实际案例应用,所以只能自己动手写一本。本书也有点像是自己的笔记,我也会经常翻翻,让自己的头脑始终保持清晰思路。

3. 读者对象

本书适合以下所有R语言工作者:

  • R语言的学习者和使用者(必读)
  • 金融宽客(Quant)(必读)
  • 计算机背景的金融量化爱好者(必读)
  • 数据分析背景的金融方向数据科学家(必读)
  • 统计背景的金融科研工作者
  • 金融行业从业者,券商研究员、分析师、基金经理
  • 回归中国市场的海外金融量化从业人员
  • 金融、统计、数据科学专业的学生

4. 如何阅读本书

本书分为三个部分,六个章节,每一个章节都是一块大的知识体系。

  • 第一部分是金融市场与金融理论(第1~2章),从了解金融开始,建立对金融认识的基本思路。
  • 第二部分是R语言数据处理与高性能计算(第3~4章),详细介绍了R语言进行数据处理的必备工具和使用方法。
  • 第三部分是金融策略实战(第5~6章),结合R语言技术和金融知识,解决金融量化领域的实际问题。

第一章,金融市场概述,为全书开篇,主要介绍了如何R语言做量化投资的思路和方法。量化投资是跨学科知识结合的一个方向,包括了R语言的技术层面的知识,基础学科的应用和金融市场的情况。R语言社区提供丰富的金融工具包,可以让我们快速构建量化投资的体系结构。本章内容以我个人的从业体会,从数据的角度观察中国的金融市场,发现机会,找到风口。

第二章,金融理论,主要介绍了金融经典理论模型和R语言的实现方法。用R语言深度解读,投资学理论和统计学理论在实际金融市场中的应用,包括4个基础理论模型,资本资产定价模型、一元回归性线模型、多元回归线性模型、自回归模型,希望这些基础理论模型可以帮助读者,找到理解金融市场的方法。

第三章,R语言数据处理。以R语言数据处理技术为核心,介绍了如何用R语言进行各种类型数据的处理方法,包括标准的结构化数据集的处理和字符数据集的处理,同时深入浅出地介绍了R语言数据处理方式,包括循环、分组、合并、管道、分词等的常用数据处理操作。

第四章,R语言高性能计算。R语言的性能问题一直是被大家所关心的,R本身有很多解决方案来提高性能,但由于R语言内核的单线程设计,让R本身的解决方案有飞跃式的性能提升是困难的。本章将介绍通过3种外部技术,来让R语言的性能达到生产环境的要求。

第五章,债券和回购。金融市场很大,不仅有股票,更大市场是债券。本章重点介绍了如何用R语言去进行债券分析,做一些债券投资和套利。低风险的债券投资,说不定是我们投资理财更好的选择。

第六章,量化投资策略案例。本章全部是综合的案例,从金融市场开始研究,到数学公式,R语言建模,历史数据回测,最后找到投资机会,是一套完整的从理论到实践的学习方法。祝大家在金融市场中玩的开心!

本书有很多综合运用的知识,在您阅读本书的时候,建议读者顺序阅读全部的章节。本书的一些技术实现,用到了我前两本书介绍的知识点,《R的极客理想-高级开发篇》和《R的极客理想-工具篇》,建议读者一起阅读。

5. 致谢

感谢在我最失意的时候,帮助我度过难关的朋友,北京千庄智金科技有限责任公司总经理张颂,量子金服CEO刘亚非,民生银行同事许斌。 感谢所有R语言的读者,以及社区的各位朋友,让我们通过R语言认识,并一起把知识进行传播。 感谢天善智能社区CEO梁勇,为本书提供赞助和推广。同时,感谢台湾銓智金融科技合伙人陈琪龙博士,复旦大学黄达教授,为本书写推荐序。感谢机械工业出版社华章公司的主编 杨福川 和编辑 李艺,帮助我审阅全部章节,让本书得以出版。

特别感谢我的爱人一直在鼓励我,最终让我走出了失意的阴影。感谢我的爸爸、妈妈,感谢你们对我工作上的支持和生活上的照顾!小宝宝,也在今年出生。

谨以此书献给我最亲爱的家人以及众多R语言爱好者们!祝大家阅读愉快,欢迎交流。

转载请注明出处:
http://blog.fens.me/r-book3/

打赏作者

2017微软技术暨生态大会:R语言搭建多因子体系

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹, 程序员R,Nodejs,Java
  • weibo:@Conan_Z
  • blog:http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-ms-20171103

前言

微软的技术大会,够规模,够档次,更切身地感受到,微软已经变得开放了!同时,微软股价创造了历史新高,比尔盖茨来华访问。

在本次大会上,我主要介绍的是开源技术R语言,在金融量化投资领域的应用。本次分享,仅仅从传播知识的角度,用IT人能够理解的语言,说出基金经理在做的事情

目录

  1. 我的演讲主题:R语言搭建多因子体系
  2. 会议体验和照片分享

1. 我的演讲主题:R语言搭建多因子体系

感谢微软对于MVP获得者的邀请,让MVP有展示个人能力的机会。我本次分享的主题为:R语言搭建多因子体系,主要内容来自我的一篇博文:R语言搭建多因子体系(未发布)。

分享主题的目录大纲如下:

  1. 故事开始
  2. 金融理论
  3. 多因子体系
  4. R语言建模
  5. 实例应用

本此分析主要是从金融的角度切入,介绍多因子的体系,进行选股,并通过R语言进行实现的。多因子方法选股,是目前主流的主动型基金的选股操作方法。本次分享,从一个故事引入,让没有金融背景的朋友,也能快速进入场景。用IT人能够理解的语言,说出基金经理在做的事情。

同时,我也在致力于推动R语言在中国金融领域的发展,让R可以给更多的用户使用,培养出更多的数据分析师。也希望让我们中国人的技术能够走出去到世界的舞台。希望多能认识志同道合的朋友,一起做一些事情。

2. 会议体验和照片分享

会议的主页:https://www.microsoft.com/china/techsummit/2017/

本次微软大会由百个主题组成,主要是微软的产品技术介绍。我被安装在11月03月下午的分享。让我没想到的是R语言相关的主题有3个,只不过大家的兴趣点似乎并不在数据分析或R语言。作为小众的R语言,还要有很长的路要走啊!

我的介绍和照片分享。

2.2 会议相关照片

本次的场地在 北京国际饭店会议中心,展位上也有各种新技术,和新厂商。

xbox和VR

金融解决方案

现代化工作模式

大学师弟,看起来比我压力还大。

本次大会办出世界企业的水平,希望明年有机会去微软总部西雅图,参加2018 MVP Global大会。我要赶紧准备签证去!

转载请注明出处:
http://blog.fens.me/meeting-ms-20171103

打赏作者

R语言数据科学新类型tibble

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹, 程序员R,Nodejs,Java
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-tibble/

前言

最近正在整理用R语言进行数据处理的操作方法,发现了 RStudio 公司开发的数据科学工具包tidyverse,一下子就把我吸引了。通过2天时间,我把tidyverse项目整体的学了一遍,给我的启发是非常大的。tidyverse 重新定义了数据科学的工作路径,而且路径上每个核心节点,都定义了对应的R包。这真是一项造福数据分析行业的工程,非常值得称赞!!

tidyverse个项目,包括了一系列的子项目,其中tibble被定义为取代传统data.frame的数据类型,完全有颠覆R的数据操作的可能。跟上R语言领袖的脚步,领先进入数据科学新的时代。

目录

  1. tibble介绍
  2. tibble安装
  3. tibble包的基本使用
  4. tibble的源代码分析

1. tibble介绍

tibble是R语言中一个用来替换data.frame类型的扩展的数据框,tibble继承了data.frame,是弱类型的,同时与data.frame有相同的语法,使用起来更方便。tibble包,也是由Hadley开发的R包。

tibble对data.frame做了重新的设定:

  • tibble,不关心输入类型,可存储任意类型,包括list类型
  • tibble,没有行名设置 row.names
  • tibble,支持任意的列名
  • tibble,会自动添加列名
  • tibble,类型只能回收长度为1的输入
  • tibble,会懒加载参数,并按顺序运行
  • tibble,是tbl_df类型

tibble的项目主页:https://github.com/tidyverse/tibble

2. tibble安装

本文所使用的系统环境

  • Win10 64bit
  • R: 3.2.3 x86_64-w64-mingw32/x64 b4bit

tibble是在CRAN发布的标准库,安装起来非常简单,2条命令就可以了。


~ R
> install.packages('tibble')
> library(tibble)

RStudio官方把tibble项目,集成到了tidyverse项目中了,官方建议直接安装tidyverse项目,这样整个用来做数据科学的库都会被下载下来。


~ R
> install.packages('tidyverse')
> library(tidyverse)
#> Loading tidyverse: ggplot2
#> Loading tidyverse: tibble
#> Loading tidyverse: tidyr
#> Loading tidyverse: readr
#> Loading tidyverse: purrr
#> Loading tidyverse: dplyr
#> Conflicts with tidy packages ----------------------------------------------
#> filter(): dplyr, stats
#> lag():    dplyr, stats

tidyverse项目,是一个包括了数据科学的一个集合工具项目,用于数据提取,数据清理,数据类型定义,数据处理,数据建模,函数化编程,数据可视化,包括了下面的包。

  • ggplot2, 数据可视化
  • dplyr, 数据处理
  • tidyr, 数据清理
  • readr, 数据提取
  • purrr, 函数化编程
  • tibble, 数据类型定义

tidyverse项目的地址:https://github.com/tidyverse/tidyverse。高效的使用R语言做数据科学,请参考开源图书 R for Data Science.

3. tibble包的基本使用

对于tibble包的使用,主要需要掌握创建、数据转型、数据查看、数据操作、与data.frame的区别点。复杂的数据处理功能,是dplyr项目来完成,下一篇讲dplyr的文章再给大家介绍。

3.1 创建tibble

创建一个tibble类型的data.frame是非常简单的,语法与传统的data.frame是类似的。


# 创建一个tibble类型的data.frame
> t1<-tibble(1:10,b=LETTERS[1:10]);t1
# A tibble: 10 x 2
   `1:10`     b
    <int> <chr>
 1      1     A
 2      2     B
 3      3     C
 4      4     D
 5      5     E
 6      6     F
 7      7     G
 8      8     H
 9      9     I
10     10     J

# 创建一个data.frame
> d1<-data.frame(1:10,b=LETTERS[1:10]);d1
   X1.10 b
1      1 A
2      2 B
3      3 C
4      4 D
5      5 E
6      6 F
7      7 G
8      8 H
9      9 I
10    10 J

从上面的输出可以看到tibble类型,会在输出时多一行,用来指定每一列的类型。

tibble用缩写定义了7种类型:

  • int,代表integer
  • dbl,代表double
  • chr,代表character向量或字符串。
  • dttm,代表日期+时间(a date + a time)
  • lgl,代表逻辑判断TRUE或者FALSE
  • fctr,代表因子类型factor
  • date,代表日期dates.

查看类型,发现tbl_df继承了tbl继承是data.frame,所以tibble是data.frame的子类型。


# t1为tbl_df类型
> class(t1)
[1] "tbl_df"     "tbl"        "data.frame"

# 是data.frame类型
> class(d1)
[1] "data.frame"

让我们多角度来观察t1变量。


# 判断是不是tibble类型
> is.tibble(t1)
[1] TRUE

# 查看t1的属性
> attributes(t1)
$names
[1] "1:10" "b"   

$class
[1] "tbl_df"     "tbl"        "data.frame"

$row.names
 [1]  1  2  3  4  5  6  7  8  9 10

# 查看t1的静态结构
> str(t1)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':	10 obs. of  2 variables:
 $ 1:10: int  1 2 3 4 5 6 7 8 9 10
 $ b   : chr  "A" "B" "C" "D" ...

通过文本排列来创建一个tibble


> tribble(
+   ~colA, ~colB,
+   "a",   1,
+   "b",   2,
+   "c",   3
+ )
# A tibble: 3 x 2
   colA  colB
  <chr> <dbl>
1     a     1
2     b     2
3     c     3

通过vector创建tibble


> tibble(letters)
# A tibble: 26 x 1
   letters
     <chr>
 1       a
 2       b
 3       c
 4       d
 5       e
 6       f
 7       g
 8       h
 9       i
10       j
# ... with 16 more rows

通过data.frame创建tibble,这时就会报错了。


> tibble(data.frame(1:5))
Error: Column `data.frame(1:5)` must be a 1d atomic vector or a list

通过list创建tibble


> tibble(x = list(diag(1), diag(2)))
# A tibble: 2 x 1
              x
         <list>
1 <dbl [1 x 1]>
2 <dbl [2 x 2]>

我们看到tibble其实是存储list类型,这是data.frame做不到的。

通过一个tibble,创建另一个tibble,这时也会报错了。

> tibble(x = tibble(1, 2, 3))
Error: Column `x` must be a 1d atomic vector or a list

3.2 数据类型转换

tibble是一个新的类型,R语言中大部分的数据都是基于原有的数据类型,所以原有数据类型与tiblle类型的转换就显的非常重要了。

把一个data.frame的类型的转换为tibble类型


# 定义一个data.frame类型变量
> d1<-data.frame(1:5,b=LETTERS[1:5]);d1
  X1.5 b
1    1 A
2    2 B
3    3 C
4    4 D
5    5 E

# 把data.frame转型为tibble
> d2<-as.tibble(d1);d2
# A tibble: 5 x 2
   X1.5      b
  <int> <fctr>
1     1      A
2     2      B
3     3      C
4     4      D
5     5      E

# 再转回data.frame
> as.data.frame(d2)
  X1.5 b
1    1 A
2    2 B
3    3 C
4    4 D
5    5 E

我们可以看到tibble与data.frame的转型是非常平滑的,一个转型函数就够,不需要中间做任何的特殊处理。

把一个vector转型为tibble类型,但是不能再转回vector了。


# vector转型到tibble
> x<-as.tibble(1:5);x
# A tibble: 5 x 1
  value
  <int>
1     1
2     2
3     3
4     4
5     5

# tibble转型到vector, 不成功
> as.vector(x)
# A tibble: 5 x 1
  value
  <int>
1     1
2     2
3     3
4     4
5     5

把list转型为tibble。


# 把list转型为tibble
> df <- as.tibble(list(x = 1:500, y = runif(500), z = 500:1));df
# A tibble: 500 x 3
       x          y     z
   <int>      <dbl> <int>
 1     1 0.59141749   500
 2     2 0.61926125   499
 3     3 0.06879729   498
 4     4 0.69579561   497
 5     5 0.05087461   496
 6     6 0.63172517   495
 7     7 0.41808985   494
 8     8 0.78110219   493
 9     9 0.95279741   492
10    10 0.98930640   491
# ... with 490 more rows

# 把tibble再转为list
> str(as.list(df))
List of 3
 $ x: int [1:500] 1 2 3 4 5 6 7 8 9 10 ...
 $ y: num [1:500] 0.5914 0.6193 0.0688 0.6958 0.0509 ...
 $ z: int [1:500] 500 499 498 497 496 495 494 493 492 491 ...

tibble与list的转型也是非常平滑的,一个转型函数就够。

把matrix转型为tibble。


# 生成一个matrix
> m <- matrix(rnorm(15), ncol = 5)

# matrix转为tibble
> df <- as.tibble(m);df
# A tibble: 3 x 5
          V1         V2         V3         V4         V5
                               
1  0.8436494  2.1420238  0.2690392 -0.4752708 -0.2334994
2  1.0363340  0.8653771 -0.3200777 -1.7400856  1.2253651
3 -0.2170344 -1.1346455  0.2204718  1.2189431  0.7020156

# tibble转为matrix
> as.matrix(df)
             V1         V2         V3         V4         V5
[1,]  0.8436494  2.1420238  0.2690392 -0.4752708 -0.2334994
[2,]  1.0363340  0.8653771 -0.3200777 -1.7400856  1.2253651
[3,] -0.2170344 -1.1346455  0.2204718  1.2189431  0.7020156

从上面的转型测试可以看到,tibble类型是非常友好的,可以与data.frame, list, matrix 进行相互转型操作。tibble与vector是不能进行直接转型的,这与data.frame的行为是一致的,如果需要转型,我们可以分别取出每一列进行拼接,或转为matrix再操作。

3.3 tibble数据查询

通常我们是str()函数来观察数据的静态组成结果,在tibble包提供了一个glimpse(),可以方便我们来观察tibble和data.frame类型的数据。

比较glimpse()和str()对于data.frame的数据查看输出


> glimpse(mtcars)
Observations: 32
Variables: 11
$ mpg   21.0, 21.0, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2, 17.8, 16.4, 17....
$ cyl   6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, ...
$ disp  160.0, 160.0, 108.0, 258.0, 360.0, 225.0, 360.0, 146.7, 140.8, 167.6, 167.6...
$ hp    110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, 180, 180, 205, 215...
$ drat  3.90, 3.90, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92, 3.07, 3.0...
$ wt    2.620, 2.875, 2.320, 3.215, 3.440, 3.460, 3.570, 3.190, 3.150, 3.440, 3.440...
$ qsec  16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20.00, 22.90, 18.30, 18.90...
$ vs    0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, ...
$ am    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, ...
$ gear  4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3, 3, ...
$ carb  4, 4, 1, 1, 2, 1, 4, 2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2, 2, 4, 2, ...

# 打印静态结构
> str(mtcars)
'data.frame':	32 obs. of  11 variables:
 $ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
 $ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
 $ disp: num  160 160 108 258 360 ...
 $ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
 $ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
 $ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
 $ qsec: num  16.5 17 18.6 19.4 17 ...
 $ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
 $ am  : num  1 1 1 0 0 0 0 0 0 0 ...
 $ gear: num  4 4 4 3 3 3 3 4 4 4 ...
 $ carb: num  4 4 1 1 2 1 4 2 2 4 ...

比较glimpse()和str()对于tibble的数据查看输出。


# 新建tibble
> df <- tibble(x = rnorm(500), y = rep(LETTERS[1:25],20))

# 查看df
> glimpse(df)
Observations: 500
Variables: 2
$ x  -0.3295530, -2.0440424, 0.1444697, 0.8752439, 1.7705952, 0.5898253, 0.1991844,...
$ y  "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P"...

# 查看df静态结构
> str(df)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':	500 obs. of  2 variables:
 $ x: num  -0.33 -2.044 0.144 0.875 1.771 ...
 $ y: chr  "A" "B" "C" "D" ...

按列出数据,一层[]返回的结果还是tibbe,二层[]与$返回的结果为列组成的向量。


> df <- tibble(x = 1:3, y = 3:1)

# 按列取,返回tibble
> df[1]
# A tibble: 3 x 1
      x
  <int>
1     1
2     2
3     3

# 按列取,返回向量
> df[[1]]
[1] 1 2 3
> df$x
[1] 1 2 3

按行取数据,这时一定要用,来做分隔符


# 取第一行
> df[1,]
# A tibble: 1 x 2
      x     y
  <int> <int>
1     1     3

# 取前2行
> df[1:2,]
# A tibble: 2 x 2
      x     y
  <int> <int>
1     1     3
2     2     2

# 取第二列的2,3行
> df[2:3,2]
# A tibble: 2 x 1
      y
  <int>
1     2
2     1

3.4 tibble数据操作

增加一列。


# 创建一个tibble
> df <- tibble(x = 1:3, y = 3:1);df
# A tibble: 3 x 2
      x     y
  <int> <int>
1     1     3
2     2     2
3     3     1

# 增加一列
> add_column(df, z = -1:1, w = 0)
# A tibble: 3 x 4
      x     y     z     w
  <int> <int> <int> <dbl>
1     1     3    -1     0
2     2     2     0     0
3     3     1     1     0

增加一行,还是基于上面生成的df变量。


# 在最后,增加一行
> add_row(df, x = 99, y = 9)
# A tibble: 4 x 2
      x     y
  <dbl> <dbl>
1     1     3
2     2     2
3     3     1
4    99     9

# 插入第二行,增加一行
> add_row(df, x = 99, y = 9, .before = 2)
# A tibble: 4 x 2
      x     y
  <dbl> <dbl>
1     1     3
2    99     9
3     2     2
4     3     1

3.5 tibble与data.frame的区别

列名,可以自由定义,并且会自动补全。


> tb <- tibble(
+   `:)` = "smile",
+   ` ` = "space",
+   `2000` = "number",
+   `列名` = "hi",
+   1,1L
+ )
> tb
# A tibble: 1 x 6
   `:)`   ` ` `2000`  列名   `1`  `1L`
  <chr> <chr>  <chr> <chr> <dbl> <int>
1 smile space number    hi     1     1

数据,按顺序执行懒加载。


> a <- 1:5
> tibble(a, b = a * 2)
# A tibble: 5 x 2
      a     b
  <int> <dbl>
1     1     2
2     2     4
3     3     6
4     4     8
5     5    10

打印输出控制,tibble的打印控制被重写了,所以执行print()函数时,模型会先进行类型匹配,然后调用print.tbl()。


# 创建tiblle
> tb<-tibble(a=1:5, b = a * 2, c=NA, d='a', e=letters[1:5])

# 打印前10行,不限宽度
> print(tb,n = 10, width = Inf)
# A tibble: 5 x 5
      a     b     c     d     e
  <int> <dbl> <lgl> <chr> <chr>
1     1     2    NA     a     a
2     2     4    NA     a     b
3     3     6    NA     a     c
4     4     8    NA     a     d
5     5    10    NA     a     e

# 打印前3行,宽度30
> print(tb,n = 3, width = 30)
# A tibble: 5 x 5
      a     b     c     d
  <int> <dbl> <lgl> <chr>
1     1     2    NA     a
2     2     4    NA     a
3     3     6    NA     a
# ... with 2 more rows, and 1
#   more variables: e 

# 用print函数,打印data.frame
> df<-data.frame(tb)
> print(df)
  a  b  c d e
1 1  2 NA a a
2 2  4 NA a b
3 3  6 NA a c
4 4  8 NA a d
5 5 10 NA a e

3.7 特殊的函数

lst,创建一个list,具有tibble特性的list。 lst函数的工作原理,类似于执行[list()],这样的操作。


# 创建一个list,懒加载,顺序执行
> lst(n = 5, x = runif(n))
$n
[1] 5
$x
[1] 0.6417069 0.2674489 0.5610810 0.1771051 0.1504583

enframe,快速创建tibble。enframe提供了一个模板,只有2列name和value,快速地把2个向量匹配的tibble中,可以按行生成或按列生成。


# 按列生成
> enframe(1:3)
# A tibble: 3 x 2
   name value
  <int> <int>
1     1     1
2     2     2
3     3     3

# 按行生成
> enframe(c(a = 5, b = 7))
# A tibble: 2 x 2
   name value
  <chr> <dbl>
1     a     5
2     b     7

deframe,把tibble反向转成向量,这个函数就实现了,tibble到向量的转换。它默认把name列为索引,用value为值。


# 生成tibble
> df<-enframe(c(a = 5, b = 7));df
# A tibble: 2 x 2
   name value
  <chr> <dbl>
1     a     5
2     b     7

# 转为vector
> deframe(df)
a b 
5 7 

3.8 用于处理data.frame函数

tibble还提供了一些用于处理data.frame的函数。


# 创建data.frame
> df<-data.frame(x = 1:3, y = 3:1)

# 判断是否有叫x的列
> has_name(df,'x')
[1] TRUE

# 判断是否有行名
> has_rownames(df)
[1] FALSE

# 给df增加行名
> row.names(df)<-LETTERS[1:3];df
  x y
A 1 3
B 2 2
C 3 1

# 判断是否有行名
> has_rownames(df)
[1] TRUE

# 去掉行名
> remove_rownames(df)
  x y
1 1 3
2 2 2
3 3 1

# 把行名转换为单独的一列
> df2<-rownames_to_column(df, var = "rowname");df2
  rowname x y
1       A 1 3
2       B 2 2
3       C 3 1

# 把一列设置为行名
> column_to_rownames(df2, var = "rowname")
  x y
A 1 3
B 2 2
C 3 1

# 把行索引转换为单独的一列
> rowid_to_column(df, var = "rowid")
  rowid x y
1     1 1 3
2     2 2 2
3     3 3 1

这些data.frame的工具函数,我猜是用于data.frame到tibble的数据类型转换用的,因为tiblle是没有行名的。

4. tibble的源代码分析

对于tibble包的深入理解,我们需要分析tibble包底层的源代码,以及设计原理。我们打开github上是tibble项目,找到tibble.R的源代码,先来了解一下tibble类型的定义。

找到tibble函数的定义:


tibble <- function(...) {
  xs <- quos(..., .named = TRUE)
  as_tibble(lst_quos(xs, expand = TRUE))
}

tibble函数的构成是非常简单地,用quos()和lst_quos()函数来分割参数,再用as_tibble()函数,生成tibble类型。

我们再找到as_tibble函数的定义:


as_tibble <- function(x, ...) {
  UseMethod("as_tibble")
}

as_tibble.tbl_df <- function(x, ..., validate = FALSE) {
  if (validate) return(NextMethod())
  x
}

这个函数是一个S3类型的函数,可以S3面向对象类型的方法,来查找tibble相关的重写的函数。关于S3类型的详细介绍,请参与文章R语言基于S3的面向对象编程


> methods(generic.function=as_tibble)
[1] as_tibble.data.frame* as_tibble.default*    as_tibble.list*       as_tibble.matrix*    
[5] as_tibble.NULL*       as_tibble.poly*       as_tibble.table*      as_tibble.tbl_df*    
[9] as_tibble.ts*    

利用S3的查询函数,把整个tibble类型定义的泛型化函数都找到了。

接下来,我们继续到tbl_df的类型的定义


#' @importFrom methods setOldClass
setOldClass(c("tbl_df", "tbl", "data.frame"))

最后,这样就明确了tbl_df是类的定义,包括了属性和方法,而tibble是实例化的对象。通过对tibble函数的源代码分析,了解tibble本身的结构是怎么样的。那么再接下来,就是如何利用tibble来进行用于数据科学的数据处理过程。请继续阅读下一篇文章:R语言数据科学数据处理包dplyr。

转载请注明出处:
http://blog.fens.me/r-tibble/

打赏作者