時間序列分析工具箱——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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...