時間序列分析工具箱——tibbletime

来源:https://www.cnblogs.com/xuruilong100/archive/2018/09/02/9575824.html
-Advertisement-
Play Games

[TOC] 翻譯自《Demo Week: Tidy Time Series Analysis with tibbletime》 原文鏈接:www.business science.io/code tools/2017/10/26/demo_week_tibbletime.html 註意:由於軟體包的 ...


目錄

翻譯自《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 上安裝最新開發版。

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

安裝完成後,載入下麵的包:

  • tibbletime:創建帶時間軸的 tibble 對象,可以使用 tbl_time 函數。
  • tidyquant:載入 tidyverse 框架,用 tq_get() 獲取數據。
# Load libraries
library(tibbletime) # Version: 0.1.1, Future of tidy time series analysis
library(tidyquant)  # Loads tidyverse, tq_get()

數據

tq_get() 下載 FANG(臉書、亞馬遜、網飛、谷歌)每天的股票價格。

# Stock Prices from Yahoo! Finance
FANG_symbols <- c("FB", "AMZN", "NFLX", "GOOG")

FANG_tbl_d <- FANG_symbols %>%
    tq_get(
        get = "stock.prices",
        from = "2014-01-01",
        to = "2016-12-31") 

FANG_tbl_d <- FANG_tbl_d %>%
    group_by(symbol)

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

我們設計了一個函數來按股票代碼分塊繪圖,可以在本文中重覆使用。沒有必要深究這些代碼,只要認識到我們正在創建一個 ggplot2 對象,它通過指定數據框、x、y 和 group(如果存在)等要素來創建根據“symbol”分塊的信息圖。

# Setup plotting function that can be reused later
ggplot_facet_by_symbol <- function(data,
                                   mapping)
{
    if (is.null(mapping$group))
    {
        # No groups
        g <- data %>%
            ggplot(
                mapping = mapping) +
            labs(x = quo_name(mapping$x),
                 y = quo_name(mapping$y))
    }
    else
    {
        # Deal with groups
        g <- data %>%
            ggplot(
                mapping = mapping)  +
            labs(x = quo_name(mapping$x),
                 y = quo_name(mapping$y),
                 group = quo_name(mapping$group))
    }

    # Add faceting and theme
    g <- g +
        geom_line() +
        facet_wrap(
            ~ symbol, ncol = 2, scales = "free_y") +
        scale_color_tq() +
        theme_tq()

    return(g)
}

我們可以使用繪圖函數 ggplot_facet_by_symbol 快速可視化我們的數據。讓我們看一下“除權調整的”股票價格。

# Plot adjusted vs date
FANG_tbl_d %>%
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = adjusted, color = symbol)) +
    labs(
        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 對象要跟蹤哪個索引。

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

我們可以列印 tbl_time 對象。看起來幾乎與分組的 tibble 相同。請註意,“Index: date”通知我們“time tibble”已正確初始化。

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

我們可以使用繪圖函數 ggplot_facet_by_symbol() 繪製它,我們看到 tbl_time 對象與 tbl 對象的反應相同。

# Plot the tbl_time object
FANG_tbl_time_d %>%
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = adjusted, color = symbol)) +
    labs(
        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') 來完成。

# filter_time by day
FANG_tbl_time_d %>%
    filter_time('2014-06-01' ~ '2014-06-15') %>%
    # Plotting
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = adjusted, color = symbol)) +
    geom_point() +
    labs(
        title = "Time Filter: Use functional notation to quickly subset by time",
        subtitle = "2014-06-01 ~ 2014-06-15")

我們可以按月完成同樣的工作。假設我們只想在 2014 年 3 月進行觀察。使用簡化函數標記 ~ '2014-03'

# filter_time by month
FANG_tbl_time_d %>%
    filter_time(~ '2014-03') %>%
    # Plotting
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = adjusted, color = symbol)) +
    geom_point() +
    labs(
        title = "Time Filter: Use shorthand for even easier subsetting",
        subtitle = "~ 2014-03")

tbl_time 對象也響應括弧符號運算符——[。在這裡,我們提取 2014 年所有日期的數據。

# time filter bracket [] notation
FANG_tbl_time_d[~ '2014'] %>%
    # Plotting
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = adjusted, color = symbol)) +
    labs(
        title = "Time Filter: Bracket Notation Works Too",
        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:以半年為一周期

首先,讓我們做一個簡單的月度周期性變化。

# Convert from daily to monthly periodicity
FANG_tbl_time_d %>%
    as_period(period = "month") %>%
    # Plotting
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = adjusted, color = symbol)) +
    labs(
        title = "Periodicity Change from Daily to Monthly") +
    geom_point()

讓我們提升一個檔次。那麼每兩個月一次呢? 只需使用函數標記 2 m 即可。

# Convert from daily to bi-monthly periodicity
FANG_tbl_time_d %>%
    as_period(period = '2 m') %>%
    # Plotting
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = adjusted, color = symbol)) +
    labs(
        title = "Periodicity Change to Daily to Bi-Monthly",
        subtitle = "2~m") +
    geom_point()

讓我們繼續。那麼每半年一次呢? 只需使用 6 m 即可。

# Convert from daily to bi-annually periodicity
FANG_tbl_time_d %>%
    as_period(period = '6 m') %>%
    # Plotting
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = adjusted, color = symbol)) +
    labs(
        title = "Periodicity Change to Daily to Bi-Annually",
        subtitle = "6~m") +
    geom_point()

函數標記幾乎提供了無限可能,感興趣的話可以查看 vignette on periodicity change with tibbletime

rollify

rollify() 函數是一個副詞tidyverse 中的一種特殊類型的函數,用於修改另一個函數)。rollify() 的作用是將任何函數轉換為自身的滾動版本。

# Rolling 60-day mean
roll_mean_60 <- rollify(
    mean, window = 60)

FANG_tbl_time_d %>%
    mutate(
        mean_60 = roll_mean_60(adjusted)) %>%
    select(-c(open:volume)) %>%
    # Plot
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = adjusted, color = symbol)) +
    geom_line(
        aes(y = mean_60),
        color = palette_light()[[6]]) +
    labs(
        title = "Rolling 60-Day Mean with rollify")

我們甚至可以做出更複雜的滾動功能,例如相關性。我們在 rollify() 中使用函數形式 .f = ~fun(.x,.y,...)

# Rolling correlation
roll_corr_60 <- rollify(
    ~ cor(.x, .y, use = "pairwise.complete.obs"),
    window = 60)

FANG_tbl_time_d %>%
    mutate(
        cor_60 = roll_corr_60(
            open, close)) %>%
    select(-c(open:adjusted)) %>%
    # Plot
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = cor_60, color = symbol)) +
    labs(
        title = "Rollify: 60-Day Rolling Correlation Between Open and Close Prices")

我們甚至可以返回多個結果。例如,我們可以創建滾動分位數。

首先,創建一個返回分位數的函數。

# Quantile tbl function
quantile_tbl <- function(x)
{
    q <- quantile(x)
    
    tibble(
        quantile_name  = names(q),
        quantile_value = q)
}

# Test the function
quantile_tbl(1:100)
## # A tibble: 5 x 2
##   quantile_name quantile_value
##           <chr>          <dbl>
## 1            0%           1.00
## 2           25%          25.75
## 3           50%          50.50
## 4           75%          75.25
## 5          100%         100.00

很好,它可以工作。接下來,使用 rollify 創建滾動版本。我們設置 unlist = FALSE 來返回列表列

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

接下來,在 mutate() 中應用滾動分位數函數來獲得滾動分位數。確保你已經用 select()filter()unnest() 刪除了不必要的列,過濾了 NA 值,並展開列表列。現在每個日期有五個分位數值。

# Apply rolling quantile 
FANG_quantile_60 <- FANG_tbl_time_d %>%
    mutate(
        rolling_quantile = roll_quantile_60(adjusted)) %>%
    select(-c(open:adjusted)) %>%
    filter(!is.na(rolling_quantile)) %>%
    unnest()

FANG_quantile_60
## # A time tibble: 13,940 x 4
## # Index:  date
## # Groups: symbol [4]
##    symbol       date quantile_name quantile_value
##  *  <chr>     <date>         <chr>          <dbl>
##  1     FB 2014-03-28            0%        53.5300
##  2     FB 2014-03-28           25%        57.8750
##  3     FB 2014-03-28           50%        64.2100
##  4     FB 2014-03-28           75%        68.6275
##  5     FB 2014-03-28          100%        72.0300
##  6     FB 2014-03-31            0%        53.5300
##  7     FB 2014-03-31           25%        57.9350
##  8     FB 2014-03-31           50%        64.2100
##  9     FB 2014-03-31           75%        68.6275
## 10     FB 2014-03-31          100%        72.0300
## # ... with 13,930 more rows

最後,畫出結果。

FANG_quantile_60 %>%
    ggplot_facet_by_symbol(
        mapping = aes(
            x = date, y = quantile_value,
            color = symbol, group = quantile_name)) +
    labs(
        title = "Rollify: Create Rolling Quantiles")

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 題意 約翰要帶N(1≤N≤100000)只牛去參加集會裡的展示活動,這些牛可以是牡牛,也可以是牝牛.牛們要站成一排.但是牡牛是好鬥的,為了避免牡牛鬧出亂子,約翰決定任意兩隻牡牛之間至少要有K(O≤K<N)只牝牛. 請計算一共有多少種排隊的方法.所有牡牛可以看成是相同的,所有牝牛也一樣.答案對5000 ...
  • 俗話說 「不要重覆造輪子」,關於是否有必要不再本次討論範圍。 創建這個項目的主要目的還是提升自己,看看和知名類開源項目的差距以及學習優秀的開源方式。 ...
  • 持續集成(Continuous Integration)指的是,頻繁地(一天多次)將代碼集成到主幹。 持續集成的目的,就是讓產品可以快速迭代,同時還能保持高質量。 它的核心措施是,代碼集成到主幹之前,必須通過自動化測試。只要有一個測試用例失敗,就不能集成。 持續集成可以把工程師從繁瑣的任務中解放出來 ...
  • fail-fast機制即為快速失敗機制,個人認為是一種防護措施,在集合結構發生改變的時候,使盡全力拋出ConcurrentModificationException,所以該機制大部分用途都是用來檢測Bug的; 下麵的代碼可以引發fail-fast fail-fast原理 每個集合都會實現可遍歷的介面 ...
  • 在日常的Java開發中,位運算使用的不多,使用的更多的是算數運算(+、-、*、/、%)、關係運算(<、>、<=、>=、==、!=)和邏輯運算(&&、||、!),所以相對來說對位運算不是那麼熟悉,本文將以Java的位運算來詳細介紹下位運算及其應用。 1、 位運算起源 位運算起源於C語言的低級操作,Ja ...
  • 1.分散式 把一個項目拆成幾個部分,然後分別交給不同的人或部門去完成,部門與部門之間互相團結協作共同完成這個大項目。 2.集群 集群就是大家一起幹活,負載均衡就是每個人乾的都差不多(在同一個項目里),不能把某個人累死,也不能讓某個人閑死。 3.反向代理 就是把不同的活分給不同的人去做。 4.散列表、 ...
  • (一)說明 這裡我是按自己的理解去實現的,時間複雜度和空間複雜度和演算法導論上的可能不一樣,感興趣的話參考下就行,感覺最重要的還是演算法思想。根據演算法性能去實現演算法以後再研究。 (二)計數排序 計數排序的基本思想是:對每一個輸人元素x,確定小於x 的元素個數。 利用這一信息,就 可以直接把x放到它在輸出 ...
  • 前言 說一個自己經歷過的事情,有一次我在開發一個通過csv文件批量導入交易的job的時候,在UAT環境上進行性能測試,發現執行失敗了。通過查看日誌發現,機器空間不足了, df h 一看發現32G的機器只有20k的空間,然後一看日誌文件的大小,就占了20G。日誌這東西,不能記得太多,不然影響性能而且占 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...