翻译自《Demo Week: Tidy Time Series Analysis with tibbletime》

原文链接:www.business-science.io/code-tools/2017/10/26/demo_week_tibbletime.html

注意:由于软件包的版本变化,部分代码被修改,文字有删减

时间序列分析工具箱——tibbletime

tibbletime 的用途

  1. tidy 时间序列分析的未来:基于 tbl 的新类——tbl_time,为 tibble 对象添加时间轴,赋予处理时间的能力。
  2. 时间序列函数:为 tbl_time 对象专门设计的一系列函数,例如:
    • filter_time():根据日期简便快捷地过滤一个 tbl_time 对象。
    • as_period():转换时间周期(例如月度变为年度),让用户能将数据聚合到低粒度水平上。
    • time_collapse():当使用 time_collapse 时,tbl_time 对象中落入相同周期的索引将被修改成相同的日期。
    • rollify():修改一个函数,使其能够在特定时间区间上计算一个或一组值。可以用来计算滚动均值,或其他 tidyverse 框架下的滚动计算。
    • create_series():根据规则时间序列,用简化标记快速初始化一个带有 datetbl_time 对象。

加载包

tibbletime 目前还在活跃开发阶段,可以用常规方法安装,也可以借助 devtools 从 github 上安装最新开发版。

  1. # Get tibbletime version with latest features
  2. devtools::install_github("business-science/tibbletime")

安装完成后,加载下面的包:

  • tibbletime:创建带时间轴的 tibble 对象,可以使用 tbl_time 函数。
  • tidyquant:加载 tidyverse 框架,用 tq_get() 获取数据。
  1. # Load libraries
  2. library(tibbletime) # Version: 0.1.1, Future of tidy time series analysis
  3. library(tidyquant) # Loads tidyverse, tq_get()

数据

tq_get() 下载 FANG(脸书、亚马逊、网飞、谷歌)每天的股票价格。

  1. # Stock Prices from Yahoo! Finance
  2. FANG_symbols <- c("FB", "AMZN", "NFLX", "GOOG")
  3. FANG_tbl_d <- FANG_symbols %>%
  4. tq_get(
  5. get = "stock.prices",
  6. from = "2014-01-01",
  7. to = "2016-12-31")
  8. FANG_tbl_d <- FANG_tbl_d %>%
  9. group_by(symbol)
  10. FANG_tbl_d
  1. ## # A tibble: 3,024 x 8
  2. ## # Groups: symbol [4]
  3. ## symbol date open high low close volume adjusted
  4. ## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
  5. ## 1 FB 2014-01-02 54.83 55.22 54.19 54.71 43195500 54.71
  6. ## 2 FB 2014-01-03 55.02 55.65 54.53 54.56 38246200 54.56
  7. ## 3 FB 2014-01-06 54.42 57.26 54.05 57.20 68852600 57.20
  8. ## 4 FB 2014-01-07 57.70 58.55 57.22 57.92 77207400 57.92
  9. ## 5 FB 2014-01-08 57.60 58.41 57.23 58.23 56682400 58.23
  10. ## 6 FB 2014-01-09 58.65 58.96 56.65 57.22 92253300 57.22
  11. ## 7 FB 2014-01-10 57.13 58.30 57.06 57.94 42449500 57.94
  12. ## 8 FB 2014-01-13 57.91 58.25 55.38 55.91 63010900 55.91
  13. ## 9 FB 2014-01-14 56.46 57.78 56.10 57.74 37503600 57.74
  14. ## 10 FB 2014-01-15 57.98 58.57 57.27 57.60 33663400 57.60
  15. ## # ... with 3,014 more rows

我们设计了一个函数来按股票代码分块绘图,可以在本文中重复使用。没有必要深究这些代码,只要认识到我们正在创建一个 ggplot2 对象,它通过指定数据框、x、y 和 group(如果存在)等要素来创建根据“symbol”分块的信息图。

  1. # Setup plotting function that can be reused later
  2. ggplot_facet_by_symbol <- function(data,
  3. mapping)
  4. {
  5. if (is.null(mapping$group))
  6. {
  7. # No groups
  8. g <- data %>%
  9. ggplot(
  10. mapping = mapping) +
  11. labs(x = quo_name(mapping$x),
  12. y = quo_name(mapping$y))
  13. }
  14. else
  15. {
  16. # Deal with groups
  17. g <- data %>%
  18. ggplot(
  19. mapping = mapping) +
  20. labs(x = quo_name(mapping$x),
  21. y = quo_name(mapping$y),
  22. group = quo_name(mapping$group))
  23. }
  24. # Add faceting and theme
  25. g <- g +
  26. geom_line() +
  27. facet_wrap(
  28. ~ symbol, ncol = 2, scales = "free_y") +
  29. scale_color_tq() +
  30. theme_tq()
  31. return(g)
  32. }

我们可以使用绘图函数 ggplot_facet_by_symbol 快速可视化我们的数据。让我们看一下“除权调整的”股票价格。

  1. # Plot adjusted vs date
  2. FANG_tbl_d %>%
  3. ggplot_facet_by_symbol(
  4. mapping = aes(
  5. x = date, y = adjusted, color = symbol)) +
  6. labs(
  7. title = "FANG Stocks: Adjusted Prices 2014 through 2016")

上图所显示就是我们要处理的数据,下面让我们进入 tibbletime 的教程。

教程:tibbletime

本教程将介绍下列函数的用法:

  • filter_time:对时间索引的过滤
  • as_period:改变数据的周期
  • rollify:将任意函数转换成为滚动函数

初始化一个 tbl_time 对象

在我们使用这些新函数之前,我们需要创建一个 tbl_time 对象。新类的操作几乎与普通的 tibble 对象相同。然而,它会在背后自动跟踪时间信息。

使用 as_tbl_time() 函数初始化对象。指定 index = date,这告诉 tbl_time 对象要跟踪哪个索引。

  1. # Convert to tbl_time
  2. FANG_tbl_time_d <- FANG_tbl_d %>%
  3. as_tbl_time(index = date)

我们可以打印 tbl_time 对象。看起来几乎与分组的 tibble 相同。请注意,“Index: date”通知我们“time tibble”已正确初始化。

  1. # Show the tbl_time object we created
  2. FANG_tbl_time_d
  1. ## # A time tibble: 3,024 x 8
  2. ## # Index: date
  3. ## # Groups: symbol [4]
  4. ## symbol date open high low close volume adjusted
  5. ## <chr> <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
  6. ## 1 FB 2014-01-02 54.83 55.22 54.19 54.71 43195500 54.71
  7. ## 2 FB 2014-01-03 55.02 55.65 54.53 54.56 38246200 54.56
  8. ## 3 FB 2014-01-06 54.42 57.26 54.05 57.20 68852600 57.20
  9. ## 4 FB 2014-01-07 57.70 58.55 57.22 57.92 77207400 57.92
  10. ## 5 FB 2014-01-08 57.60 58.41 57.23 58.23 56682400 58.23
  11. ## 6 FB 2014-01-09 58.65 58.96 56.65 57.22 92253300 57.22
  12. ## 7 FB 2014-01-10 57.13 58.30 57.06 57.94 42449500 57.94
  13. ## 8 FB 2014-01-13 57.91 58.25 55.38 55.91 63010900 55.91
  14. ## 9 FB 2014-01-14 56.46 57.78 56.10 57.74 37503600 57.74
  15. ## 10 FB 2014-01-15 57.98 58.57 57.27 57.60 33663400 57.60
  16. ## # ... with 3,014 more rows

我们可以使用绘图函数 ggplot_facet_by_symbol() 绘制它,我们看到 tbl_time 对象与 tbl 对象的反应相同。

  1. # Plot the tbl_time object
  2. FANG_tbl_time_d %>%
  3. ggplot_facet_by_symbol(
  4. mapping = aes(
  5. x = date, y = adjusted, color = symbol)) +
  6. labs(
  7. title = "Working with tbltime: Reacts same as tbl class")

时间序列函数

让我们看看可以用新的 tbl_time 对象做些什么。

filter_time

filter_time() 函数根据按日期简便快捷地过滤 tbl_time 对象,它使用一个函数格式(例如 'date_operator_start' ~ 'date_operator_end')。我们使用标准日期格式 YYYY-MM-DD + HH:MM:SS 指定日期运算符,但也有强大的简化标记来更有效地指定日期子集。

假设我们想要过滤出 2014-06-012014-06-15 之间的所有观察结果。我们可以使用函数标记 filter_time('2014-06-01' ~ '2014-06-15') 来完成。

  1. # filter_time by day
  2. FANG_tbl_time_d %>%
  3. filter_time('2014-06-01' ~ '2014-06-15') %>%
  4. # Plotting
  5. ggplot_facet_by_symbol(
  6. mapping = aes(
  7. x = date, y = adjusted, color = symbol)) +
  8. geom_point() +
  9. labs(
  10. title = "Time Filter: Use functional notation to quickly subset by time",
  11. subtitle = "2014-06-01 ~ 2014-06-15")

我们可以按月完成同样的工作。假设我们只想在 2014 年 3 月进行观察。使用简化函数标记 ~ '2014-03'

  1. # filter_time by month
  2. FANG_tbl_time_d %>%
  3. filter_time(~ '2014-03') %>%
  4. # Plotting
  5. ggplot_facet_by_symbol(
  6. mapping = aes(
  7. x = date, y = adjusted, color = symbol)) +
  8. geom_point() +
  9. labs(
  10. title = "Time Filter: Use shorthand for even easier subsetting",
  11. subtitle = "~ 2014-03")

tbl_time 对象也响应括号符号运算符——[。在这里,我们提取 2014 年所有日期的数据。

  1. # time filter bracket [] notation
  2. FANG_tbl_time_d[~ '2014'] %>%
  3. # Plotting
  4. ggplot_facet_by_symbol(
  5. mapping = aes(
  6. x = date, y = adjusted, color = symbol)) +
  7. labs(
  8. title = "Time Filter: Bracket Notation Works Too",
  9. subtitle = "FANG_tbl_time_d[~ 2014]")

filter_time() 有许多功能和简化标记,感兴趣的读者可以查看 filter_time vignettefilter_time function documentation

as_period

函数 as_period() 可以改变 tbl_time 对象的周期。与传统方法相比,使用此方法有两个优点:

  1. 函数标记非常灵活:yearly == y == 1 y
  2. 函数标记提供了无数周期转换的可能,例如:
    • 15 d:以 15 天为一周期
    • 2 m:以 2 月为一周期
    • 4 m:以 4 月为一周期
    • 6 m:以半年为一周期

首先,让我们做一个简单的月度周期性变化。

  1. # Convert from daily to monthly periodicity
  2. FANG_tbl_time_d %>%
  3. as_period(period = "month") %>%
  4. # Plotting
  5. ggplot_facet_by_symbol(
  6. mapping = aes(
  7. x = date, y = adjusted, color = symbol)) +
  8. labs(
  9. title = "Periodicity Change from Daily to Monthly") +
  10. geom_point()

让我们提升一个档次。那么每两个月一次呢? 只需使用函数标记 2 m 即可。

  1. # Convert from daily to bi-monthly periodicity
  2. FANG_tbl_time_d %>%
  3. as_period(period = '2 m') %>%
  4. # Plotting
  5. ggplot_facet_by_symbol(
  6. mapping = aes(
  7. x = date, y = adjusted, color = symbol)) +
  8. labs(
  9. title = "Periodicity Change to Daily to Bi-Monthly",
  10. subtitle = "2~m") +
  11. geom_point()

让我们继续。那么每半年一次呢? 只需使用 6 m 即可。

  1. # Convert from daily to bi-annually periodicity
  2. FANG_tbl_time_d %>%
  3. as_period(period = '6 m') %>%
  4. # Plotting
  5. ggplot_facet_by_symbol(
  6. mapping = aes(
  7. x = date, y = adjusted, color = symbol)) +
  8. labs(
  9. title = "Periodicity Change to Daily to Bi-Annually",
  10. subtitle = "6~m") +
  11. geom_point()

函数标记几乎提供了无限可能,感兴趣的话可以查看 vignette on periodicity change with tibbletime

rollify

rollify() 函数是一个副词tidyverse 中的一种特殊类型的函数,用于修改另一个函数)。rollify() 的作用是将任何函数转换为自身的滚动版本。

  1. # Rolling 60-day mean
  2. roll_mean_60 <- rollify(
  3. mean, window = 60)
  4. FANG_tbl_time_d %>%
  5. mutate(
  6. mean_60 = roll_mean_60(adjusted)) %>%
  7. select(-c(open:volume)) %>%
  8. # Plot
  9. ggplot_facet_by_symbol(
  10. mapping = aes(
  11. x = date, y = adjusted, color = symbol)) +
  12. geom_line(
  13. aes(y = mean_60),
  14. color = palette_light()[[6]]) +
  15. labs(
  16. title = "Rolling 60-Day Mean with rollify")

我们甚至可以做出更复杂的滚动功能,例如相关性。我们在 rollify() 中使用函数形式 .f = ~fun(.x,.y,...)

  1. # Rolling correlation
  2. roll_corr_60 <- rollify(
  3. ~ cor(.x, .y, use = "pairwise.complete.obs"),
  4. window = 60)
  5. FANG_tbl_time_d %>%
  6. mutate(
  7. cor_60 = roll_corr_60(
  8. open, close)) %>%
  9. select(-c(open:adjusted)) %>%
  10. # Plot
  11. ggplot_facet_by_symbol(
  12. mapping = aes(
  13. x = date, y = cor_60, color = symbol)) +
  14. labs(
  15. title = "Rollify: 60-Day Rolling Correlation Between Open and Close Prices")

我们甚至可以返回多个结果。例如,我们可以创建滚动分位数。

首先,创建一个返回分位数的函数。

  1. # Quantile tbl function
  2. quantile_tbl <- function(x)
  3. {
  4. q <- quantile(x)
  5. tibble(
  6. quantile_name = names(q),
  7. quantile_value = q)
  8. }
  9. # Test the function
  10. quantile_tbl(1:100)
  1. ## # A tibble: 5 x 2
  2. ## quantile_name quantile_value
  3. ## <chr> <dbl>
  4. ## 1 0% 1.00
  5. ## 2 25% 25.75
  6. ## 3 50% 50.50
  7. ## 4 75% 75.25
  8. ## 5 100% 100.00

很好,它可以工作。接下来,使用 rollify 创建滚动版本。我们设置 unlist = FALSE 来返回列表列

  1. # Rollified quantile function
  2. roll_quantile_60 <- rollify(
  3. quantile_tbl, window = 60, unlist = FALSE)

接下来,在 mutate() 中应用滚动分位数函数来获得滚动分位数。确保你已经用 select()filter()unnest() 删除了不必要的列,过滤了 NA 值,并展开列表列。现在每个日期有五个分位数值。

  1. # Apply rolling quantile
  2. FANG_quantile_60 <- FANG_tbl_time_d %>%
  3. mutate(
  4. rolling_quantile = roll_quantile_60(adjusted)) %>%
  5. select(-c(open:adjusted)) %>%
  6. filter(!is.na(rolling_quantile)) %>%
  7. unnest()
  8. FANG_quantile_60
  1. ## # A time tibble: 13,940 x 4
  2. ## # Index: date
  3. ## # Groups: symbol [4]
  4. ## symbol date quantile_name quantile_value
  5. ## * <chr> <date> <chr> <dbl>
  6. ## 1 FB 2014-03-28 0% 53.5300
  7. ## 2 FB 2014-03-28 25% 57.8750
  8. ## 3 FB 2014-03-28 50% 64.2100
  9. ## 4 FB 2014-03-28 75% 68.6275
  10. ## 5 FB 2014-03-28 100% 72.0300
  11. ## 6 FB 2014-03-31 0% 53.5300
  12. ## 7 FB 2014-03-31 25% 57.9350
  13. ## 8 FB 2014-03-31 50% 64.2100
  14. ## 9 FB 2014-03-31 75% 68.6275
  15. ## 10 FB 2014-03-31 100% 72.0300
  16. ## # ... with 13,930 more rows

最后,画出结果。

  1. FANG_quantile_60 %>%
  2. ggplot_facet_by_symbol(
  3. mapping = aes(
  4. x = date, y = quantile_value,
  5. color = symbol, group = quantile_name)) +
  6. labs(
  7. title = "Rollify: Create Rolling Quantiles")

如果想继续探索 rollify 的用法,可以查看 vignette on rolling functions with rollify

时间序列分析工具箱——tibbletime的更多相关文章

  1. 时间序列分析工具箱——tidyquant

    目录 时间序列分析工具箱--tidyquant tidyquant 的用途 加载包 tq_get:获得数据 从 Yahoo! Finance 获得股票数据 从 FRED 获得经济数据 使用 tq_tr ...

  2. 时间序列分析工具箱——sweep

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/kMD8d5R/article/details/81977856 作者:徐瑞龙.量化分析师,R语言中文 ...

  3. 时间序列分析工具箱—— h2o + timetk

    目录 时间序列分析工具箱-- h2o + timetk h2o 的用途 加载包 安装 h2o 加载包 数据 教程:h2o + timetk,时间序列机器学习 时间序列机器学习 最终的胜利者是... 翻 ...

  4. 时间序列分析工具箱——timetk

    目录 时间序列分析工具箱--timetk timetk 的主要用途 加载包 数据 timetk 教程: PART 1:时间序列机器学习 PART 2:转换 翻译自<Demo Week: Time ...

  5. SPSS时间序列分析

    时间序列分析必须建立在预处理的基础上…… 今天看了一条新闻体会到了网络日志的重要性…… 指数平滑法(Exponential Smoothing,ES)是布朗(Robert G..Brown)所提出,布 ...

  6. 时间序列分析算法【R详解】

    简介 在商业应用中,时间是最重要的因素,能够提升成功率.然而绝大多数公司很难跟上时间的脚步.但是随着技术的发展,出现了很多有效的方法,能够让我们预测未来.不要担心,本文并不会讨论时间机器,讨论的都是很 ...

  7. python时间序列分析

              题记:毕业一年多天天coding,好久没写paper了.在这动荡的日子里,也希望写点东西让自己静一静.恰好前段时间用python做了一点时间序列方面的东西,有一丁点心得体会想和大家 ...

  8. pandas小记:pandas时间序列分析和处理Timeseries

    http://blog.csdn.net/pipisorry/article/details/52209377 其它时间序列处理相关的包 [P4J 0.6: Periodic light curve ...

  9. 基于 Keras 的 LSTM 时间序列分析——以苹果股价预测为例

    简介 时间序列简单的说就是各时间点上形成的数值序列,时间序列分析就是通过观察历史数据预测未来的值.预测未来股价走势是一个再好不过的例子了.在本文中,我们将看到如何在递归神经网络的帮助下执行时间序列分析 ...

随机推荐

  1. oracle 用户对象权限

    drop user test cascade;create user test identified by test;grant create session to test;grant create ...

  2. BS网站架构演变

    BS网站架构演变 网站架构的整个演变过程主要是围绕大数据和高并发这两个问题展开的,解决的方案主要分为使用缓存和使用多资源两种类型.多资源主要指多存储(包括多内存).多CPU和多网络,对于多资源来说又可 ...

  3. Maven安装及MyEclipse中使用Maven

    Step1:下载mavenhttp://maven.apache.org/download.cgi,下载好后解压到一个路径中 Step2:配置环境变量, 新建变量名:MAVEN_HOME 变量值:D: ...

  4. java笔记--守护线程的应用

    守护线程的应用 Java中的线程可以分为两类,即用户线程和守护线程.用户线程是为了完成任务,而守护线程是为其他线程服务 --如果朋友您想转载本文章请注明转载地址"http://www.cnb ...

  5. poj_3628 Bookshelf 2

    Description Farmer John recently bought another bookshelf for the cow library, but the shelf is gett ...

  6. September 13th 2017 Week 37th Wednesday

    Whenever people agree with me, I always feel I must be wrong. 每次人们赞同我时,我都觉得自己一定错了. We can draw lesso ...

  7. fun() 的 拆分和 for 遍历 的结合---------> 函数容器

    fun() 的 拆分和 for 遍历 的结合--------->  函数容器

  8. [转载并收藏]JavaScript 疲劳终极指南:我们行业的真相

    这篇文章说的深得我心,特别是前半段. 特此收藏. 中文译文:http://www.zcfy.cc/article/the-ultimate-guide-to-javascript-fatigue-re ...

  9. KVOController原理解析

    1.使用类似动态代理的模式和消息派发中枢模式实现整个架构: 2.使用NSMapTable和NSHashTable进行切面信息的增删查维护:主要用于去重和查看是否存在. 实现方式 消息流 KVOCont ...

  10. AE-----界面介绍

    AE-----界面介绍 一.大纲leiji 层级: 比如:高楼一层一层的盖起来的.千层蛋糕(一层一层的).地质(一层一层构造的) 图层的特征:有顺序.上面的一层总会覆盖掉下面的一层. AfterEff ...