Tag: Time series analysis

  • 7 วิธีทำงานกับ time series data ในภาษา R: Base R, lubridate, และ zoo packages — ตัวอย่างการวิเคราะห์ราคา Bitcoin

    7 วิธีทำงานกับ time series data ในภาษา R: Base R, lubridate, และ zoo packages — ตัวอย่างการวิเคราะห์ราคา Bitcoin

    ในบทความนี้ เราจะมาเรียนรู้ 7 วิธีการทำงานกับ time series data หรือข้อมูลที่จัดเรียงด้วยเวลา ในภาษา R ผ่านการทำงานกับ Bitcoin Historical Data ซึ่งมีข้อมูล Bitcoin ในช่วงปี ค.ศ. 2010–2024 กัน:

    1. Converting: การแปลงข้อมูลเป็น datetime และ time series
    2. Missing values: การจัดการ missing values ใน time series data
    3. Plotting: การสร้างกราฟ time series data
    4. Subsetting: การเลือกข้อมูลจาก time series data
    5. Aggregating: การสรุป time series data
    6. Rolling window: การทำ rolling window
    7. Expanding window: การทำ expanding window

    ถ้าพร้อมแล้วไปเริ่มกันเลย


    🏁 Getting Started

    ในการเริ่มทำงานกับ time series ในภาษา R เราจะเริ่มต้นจาก 2 อย่าง ได้แก่:

    1. Install and load packages
    2. Load dataset

    .

    1️⃣ Install & Load Packages

    ในภาษา R เรามี 3 packages ที่ใช้ทำงานกับ time series data บ่อย ๆ ได้แก่:

    1. Base R packages ที่มาพร้อมกับภาษา R
    2. lubridate: ใช้แปลงข้อมูลและจัด format ของ date-time data
    3. zoo: ใช้ทำงานกับ time series data

    ในการเริ่มต้นใช้งาน เราจะติดตั้ง packages เหล่านี้กัน:

    # Install packages
    install.packages("lubridate"
    install.packages("zoo")
    install.packages("ggplot2") # for data visualisation
    

    จากนั้น เรียกใช้งาน packages:

    # Load packages
    library(lubridate)
    library(zoo)
    library(ggplot2) # for data visualisation
    

    Note: เราเพิ่ม ggplot2 เข้ามาด้วย เพื่อช่วยในการสร้างกราฟในภายหลัง

    .

    2️⃣ Load Dataset

    หลังติดตั้งและเรียกใช้งาน packages เราจะโหลด Bitcoin Historical Data (ดาวน์โหลดไฟล์ได้ที่ Kaggle) เข้ามาใน environment:

    # Load the dataset
    btc <- read.csv("btc_hist_2010-2024.csv")
    

    จากนั้น เราสามารถสำรวจข้อมูลได้ด้วย head() และ str():

    ## View the first 6 rows
    head(btc)
    
    ## View the structure
    str(btc)
    

    ผลลัพธ์ของ head():

              Date    Price     Open     High      Low   Vol. Change..
    1 Feb 09, 2024 47,545.4 45,293.3 47,710.2 45,254.2 86.85K    4.97%
    2 Feb 08, 2024 45,293.3 44,346.2 45,579.2 44,336.4 66.38K    2.15%
    3 Feb 07, 2024 44,339.8 43,088.4 44,367.9 42,783.5 48.57K    2.91%
    4 Feb 06, 2024 43,087.7 42,697.6 43,375.5 42,566.8 33.32K    0.91%
    5 Feb 05, 2024 42,697.2 42,581.4 43,532.2 42,272.5 39.26K    0.27%
    6 Feb 04, 2024 42,581.4 43,006.2 43,113.2 42,379.4 20.33K   -0.99%
    

    ผลลัพธ์ของ str():

    'data.frame':	4955 obs. of  7 variables:
     $ Date    : chr  "Feb 09, 2024" "Feb 08, 2024" "Feb 07, 2024" "Feb 06, 2024" ...
     $ Price   : chr  "47,545.4" "45,293.3" "44,339.8" "43,087.7" ...
     $ Open    : chr  "45,293.3" "44,346.2" "43,088.4" "42,697.6" ...
     $ High    : chr  "47,710.2" "45,579.2" "44,367.9" "43,375.5" ...
     $ Low     : chr  "45,254.2" "44,336.4" "42,783.5" "42,566.8" ...
     $ Vol.    : chr  "86.85K" "66.38K" "48.57K" "33.32K" ...
     $ Change..: chr  "4.97%" "2.15%" "2.91%" "0.91%" ...
    

    จากผลลัพธ์ เราจะเห็นว่า Bitcoin Historical Data มี 7 columns ด้วยกัน ได้แก่:

    No.ColumnDescription
    1Dateวันที่
    2Closeราคาปิด (USD)
    3Openราคาเปิด (USD)
    4Highราคาสูงสุด (USD)
    5Lowราคาต่ำสุด (USD)
    6Vol.ปริมาณการซื้อขาย
    7Change..การเปลี่ยนแปลงราคาจากวันก่อน (คิดเป็น %)

    นอกจากนี้ เราจะเห็นได้ว่า ทุก column เป็น character ซึ่งเราจะต้องแปลงให้เป็นประเภทข้อมูลที่ถูกต้องก่อน ซึ่งเราสามารถทำได้ดังนี้:

    1. สร้าง copy ของ btc
    2. เปลี่ยนชื่อ column (เพื่อให้ง่ายต่อการทำงาน)
    3. เปลี่ยน format ข้อมูลของ price และ volume
    4. แปลงประเภทข้อมูลจาก character เป็น numeric
    # Clean the dataset
    
    ## Make a copy of the dataset
    btc_cleaned <- btc
    
    ## Rename columns
    
    ### Create new column names
    new_col_names <- c("date",
                       "close", "open",
                       "high", "low",
                       "volume", "change")
    
    ### Rename
    colnames(btc_cleaned) <- new_col_names
    
    ### Check the results
    str(btc_cleaned)
    
    ## Convert data types
    
    ### Specify the columns to clean
    cols_to_clean <- c("close", "open",
                       "high", "low")
    
    ### Remove comma
    for (col in cols_to_clean) {
      btc_cleaned[[col]] <- gsub(",",
                                 "",
                                 btc_cleaned[[col]])
    }
    
    ### Remove "K"
    btc_cleaned$volume <- gsub("K",
                               "",
                               btc_cleaned$volume)
    
    ### Remove "%"
    btc_cleaned$change <- gsub("%",
                               "",
                               btc_cleaned$change)
    
    ### Specify columns to convert to numeric
    cols_to_num <- colnames(btc_cleaned[, -1])
    
    ### Convert data type to numeric
    for (col in cols_to_num) {
      btc_cleaned[[col]] <- as.numeric(btc_cleaned[[col]])
    }
    
    ### Check the results
    str(btc_cleaned)
    

    ผลลัพธ์:

    'data.frame':	4955 obs. of  7 variables:
     $ date  : chr  "Feb 09, 2024" "Feb 08, 2024" "Feb 07, 2024" "Feb 06, 2024" ...
     $ close : num  47545 45293 44340 43088 42697 ...
     $ open  : num  45293 44346 43088 42698 42581 ...
     $ high  : num  47710 45579 44368 43376 43532 ...
     $ low   : num  45254 44336 42784 42567 42273 ...
     $ volume: num  86.8 66.4 48.6 33.3 39.3 ...
     $ change: num  4.97 2.15 2.91 0.91 0.27 -0.99 -0.44 0.26 1.18 -0.85 ...
    

    ตอนนี้ ทุก column (ยกเว้น date) ถูกเปลี่ยนให้เป็น numeric เรียบร้อยแล้ว และชุดข้อมูลก็พร้อมจะถูกนำไปใช้งานต่อแล้ว


    🔄️ Converting

    เรามาดูวิธีแรกในการทำงานกับ time series data กัน นั่นคือ:

    1. การแปลงข้อมูลให้เป็น datetime
    2. การแปลงข้อมูลให้เป็น time series

    .

    1️⃣ การแปลงข้อมูลให้เป็น Datetime

    ในการทำงานกับ time series data เราจะต้องแปลงข้อมูลประเภทอื่น ๆ เช่น character และ numeric ให้เป็น datetime ก่อน เช่น date (เช่น “Feb 09, 2024”) ใน Bitcoin dataset

    เราสามารถแปลงข้อมูลจาก character เป็น Date ได้ 2 วิธี ดังนี้:

    .

    วิธีที่ 1. ใช้ as.Date() ซึ่งเป็น base R function และต้องการ input 2 อย่าง ได้แก่:

    1. x: ข้อมูลที่ต้องการแปลงเป็น Date
    2. format: format ของวันเวลาของข้อมูลต้นทาง (เช่น วัน-เดือน-ปี, ปี-เดือน-วัน, เดือน-วัน-ปี)
    # Convert `date` to Date
    btc_cleaned$date <- as.Date(btc_cleaned$date,
                                format = "%b %d, %Y")
    

    Note: ศึกษาการกำหนด format ได้ที่ strptime: Date-time Conversion Functions to and from Character และ Date Formats in R

    .

    วิธีที่ 2. ใช้ as_date() จาก lubridate ซึ่งเป็นที่นิยมมากกว่า as.Date() เพราะ as_date() แปลงข้อมูลให้อัตโนมัติ โดยเราไม่ต้องกำหนด format ให้:

    # Convert `date` to Date
    btc_cleaned$date <- as_date(btc_cleaned$date)
    

    จากตัวอย่าง จะเห็นได้ว่า as_date() ใช้งานง่ายกว่า as.Date()

    .

    ทั้งนี้ ทั้งสองวิธีให้ผลลัพธ์เหมือนกัน คือ แปลง character เป็น Date ซึ่งเราสามารถเช็กผลลัพธ์ได้ด้วย str():

    # Check the results
    str(btc_cleaned)
    

    ผลลัพธ์:

    'data.frame':	4955 obs. of  7 variables:
     $ date  : Date, format: "2024-02-09" "2024-02-08" "2024-02-07" ...
     $ close : num  47545 45293 44340 43088 42697 ...
     $ open  : num  45293 44346 43088 42698 42581 ...
     $ high  : num  47710 45579 44368 43376 43532 ...
     $ low   : num  45254 44336 42784 42567 42273 ...
     $ volume: num  86.8 66.4 48.6 33.3 39.3 ...
     $ change: num  4.97 2.15 2.91 0.91 0.27 -0.99 -0.44 0.26 1.18 -0.85 ...
    

    จะเห็นได้ว่า ตอนนี้ price เปลี่ยนเป็นจาก character เป็น Date เรียบร้อยแล้ว

    .

    2️⃣ การแปลงข้อมูลให้เป็น Time Series

    นอกจากการแปลงข้อมูลบางส่วนให้เป็น datetime แล้ว เรายังต้องการแปลง dataset จาก data frame ให้เป็น time series เพื่อมี index ของข้อมูล เป็น datetime

    ในภาษา R เรามี time series 2 ประเภทหลัก ได้แก่:

    1. ts ของ base R ซึ่งเหมาะกับข้อมูลที่มีความถี่คงที่ (เช่น ข้อมูลมีระยะห่างกัน 1 วัน)
    2. zoo จาก zoo package ซึ่งเหมาะกับข้อมูลที่มีความถี่ไม่คงที่ (เช่น บางข้อมูลห่างกัน 1 วัน และบางข้อมูลห่างกัน 1 เดือน)

    ในตัวอย่าง Bitcoin เราจะแปลง dataset ให้เป็น zoo กัน:

    # Convert data frame to zoo object
    
    ## Convert
    btc_zoo <- zoo(btc_cleaned[, -1],
                   order.by = btc_cleaned$date)
    
    ## Check the results
    head(btc_zoo)
    

    ผลลัพธ์:

               close open high low volume change
    2010-07-18   0.1  0.0  0.1 0.1   0.08      0
    2010-07-19   0.1  0.1  0.1 0.1   0.57      0
    2010-07-20   0.1  0.1  0.1 0.1   0.26      0
    2010-07-21   0.1  0.1  0.1 0.1   0.58      0
    2010-07-22   0.1  0.1  0.1 0.1   2.16      0
    2010-07-23   0.1  0.1  0.1 0.1   2.40      0
    

    จะเห็นได้ว่า datetime ถูกเปลี่ยนให้เป็น index ของข้อมูลแล้ว


    🤷‍♂️ Missing Values

    ในบางครั้ง เราอาจมี time series data ที่มีข้อมูลขาดหายไป ซึ่งเราอาจต้องการแทนที่ด้วยค่าบางอย่าง

    ในตัวอย่าง Bitcoin dataset เรามี missing values อยู่ใน volume ซึ่งเราสามารถเช็กได้ด้วย colSums() และ is.na() แบบนี้:

    # Count the missing values in each column
    colSums(is.na(btc_zoo))
    

    ผลลัพธ์:

     close   open   high    low volume change 
         0      0      0      0    271      0
    

    zoo package มี 3 functions ที่ช่วยให้เราแทนค่า missing values ได้ ดังนี้:

    No.FunctionDescription
    1na.fill()แทนค่าด้วยค่าที่เรากำหนด
    2na.locf()แทนค่าตามค่าของข้อมูลที่มาก่อนหน้า
    3na.approx()แทนค่าด้วยตามข้อมูลที่มาก่อนและหลัง missing values

    สำหรับ Bitcoin dataset เราจะใช้ na.approx() เนื่องจากข้อมูล Bitcoin มีความผันผวนและการแทนค่าแบบยืดหยุ่นจะดีกว่าการแทนค่าแบบกำหนดตายตัว:

    # Impute with na.approx()
    btc_zoo <- na.approx(btc_zoo)
    
    # Check the results
    colSums(is.na(btc_zoo))
    

    ผลลัพธ์:

     close   open   high    low volume change 
         0      0      0      0      0      0 
    

    ตอนนี้ missing values ถูกแทนค่าเรียบร้อย


    📈 Plotting

    การสร้างกราฟสามารถช่วยให้เราเข้าใจ time series data ได้ง่ายขึ้น

    เราสามารถทำได้ง่าย ๆ ด้วย autoplot.*() เช่น autoplot.ts() และ autplot.zoo()

    ใน Bitcoin dataset เราสามารถสร้างกราฟราคาปิดของ Bitcoin ในช่วง 2010**–**2024 ได้ด้วย autoplot.zoo() แบบนี้:

    # Plot the time series
    autoplot.zoo(btc_zoo[, "close"]) +
      
      ## Adjust line colour
      geom_line(color = "blue") +
      
      ## Add title and labels
      labs(title = "Bitcoin Closing Price Over Time (2010–2024)",
           x = "Time",
           y = "Closing Price (USD)") +
      
      ## Use minimal theme
      theme_minimal()
    

    ผลลัพธ์:

    Note: ในตัวอย่าง เราใช้ ggplot2 ช่วยตกแต่งกราฟให้เข้าใจง่ายขึ้น, สำหรับคนที่สนใจ สามารถศึกษาการใช้ ggplot2 ได้ที่ วิธีใช้ ggplot2 เพื่อสร้างกราฟอย่างมืออาชีพระดับโลก แบบ BBC และ Financial Times ในภาษา R — ตัวอย่างการสำรวจข้อมูลเพนกวินจาก palmerpenguins


    ✂️ Subsetting

    ในการทำงานกับ time series data เราอาจต้องการตัดแบ่งข้อมูลบางส่วนมาเพื่อสำรวจการเปลี่ยนแปลงของข้อมูลในช่วงเวลาที่ต้องการ

    ยกตัวอย่างเช่น เราอยากจะสำรวจการเปลี่ยนแปลงราคาปิดของ Bitcoin ในช่วง Crypto Winter (Nov 2021 – Dec 2022)

    ในภาษา R เราสามารถตัดแบ่ง time series ได้ 3 วิธี ได้แก่:

    1. window()
    2. Boolean masking
    3. Specific date

    .

    1️⃣ window()

    window() เป็น base R function ซึ่งช่วยเราเลือกช่วงเวลาได้ด้วย input 3 อย่าง:

    1. x: time series data
    2. start: วันเริ่มต้น (inclusive)
    3. end: วันสิ้นสุด (inclusive)

    เราสามารถใช้ window() สร้างกราฟได้แบบนี้:

    # Subset
    btc_winter_1 <- window(x = btc_zoo,
                           start = as.Date("2021-11-01"),
                           end = as.Date("2022-12-31"))
    
    # Plot the results
    autoplot.zoo(btc_winter_1[, "close"]) +
      
      ## Adjust line colour
      geom_line(color = "blue") +
      
      ## Add title and labels
      labs(title = "Bitcoin Closing Price During the Crypto Winter (2021–2022)",
           x = "Time",
           y = "Closing (USD)") +
      
      ## Use minimal theme
      theme_minimal()
    

    ผลลัพธ์:

    .

    2️⃣ Boolean Masking

    นอกจาก window() แล้ว เราสามารถเลือกช่วงเวลาด้วยการสร้าง Boolean mask ขึ้นมา แบบนี้:

    # Create a Boolean masking
    crypto_winter_index <- 
      index(btc_zoo) >= "2021-11-01" &
      index(btc_zoo) <= "2022-12-31"
    
    # Subset
    btc_winter_2 <- btc_zoo[crypto_winter_index, ]
    
    # Plot the results
    autoplot.zoo(btc_winter_2[, "close"]) +  
      
      ## Adjust line colour
      geom_line(color = "blue") +
      
      ## Add title and labels
      labs(title = "Bitcoin Closing Price During the Crypto Winter (2021–2022)",
           x = "Time",
           y = "Closing (USD)") +
      
      ## Use minimal theme
      theme_minimal()
    

    ผลลัพธ์:

    จะเห็นว่า กราฟของ Boolean masking เหมือนกับการใช้ window()

    .

    3️⃣ Specific Date

    ในกรณีที่เราต้องการเลือกวันแทนช่วงเวลา (เช่น ดูข้อมูล Bitcoin เมื่อเกิด halving ครั้งแรก) เราสามารถเขียนภาษา R ได้แบบนี้:

    # Subset
    btc_first_halving <- btc_zoo["2012-11-28"]
    
    # Print the result
    btc_first_halving
    

    ผลลัพธ์:

               close open high  low volume change
    2012-11-28  12.4 12.2 12.4 12.1  30.69   1.23
    

    🧮 Aggregating

    ในภาษา R เราสามารถสรุปข้อมูล time series data (เช่น หาค่าเฉลี่ย) ได้ด้วย apply.*() จาก zoo package:

    FunctionDescription
    apply.daily()สรุปข้อมูลรายวัน
    apply.weekly()สรุปข้อมูลรายสัปดาห์
    apply.quarterly()สรุปข้อมูลรายไตรมาส
    apply.yearly()สรุปข้อมูลรายปี

    โดย apply.*() ต้องการ input 2 อย่าง คือ:

    1. x: time series data
    2. FUN: การสรุปข้อมูล (เช่น mean, median, max, min)

    ยกตัวอย่างเช่น หาค่าเฉลี่ยราคาปิดของ Bitcoin ในแต่ละปี:

    # Example 1. View yearly mean closing price
    btc_yr_mean <- apply.yearly(btc_zoo[, "close"],
                                FUN = mean)
    
    # Plot the results
    autoplot.zoo(btc_yr_mean) +  
      
      ## Adjust line colour
      geom_line(color = "blue") +
      
      ## Add title and labels
      labs(title = "Bitcoin Yearly Mean Closing Price (2010–2024)",
           x = "Time",
           y = "Closing (USD)") +
      
      ## Use minimal theme
      theme_minimal()
    

    ผลลัพธ์:

    หรือหาราคาปิดสูงสุดในแต่ละไตรมาส:

    # Example 2. View quarterly max closing price
    btc_qtr_max <- apply.quarterly(btc_zoo[, "close"],
                                   FUN = max)
    
    # Plot the results
    autoplot.zoo(btc_qtr_max) +  
      
      ## Adjust line colour
      geom_line(color = "blue") +
      
      ## Add title and labels
      labs(title = "Bitcoin Quarterly Maximum Closing Price (2010–2024)",
           x = "Time",
           y = "Closing (USD)") +
      
      ## Use minimal theme
      theme_minimal()
    

    ผลลัพธ์:

    ทั้งนี้ ถ้าเราต้องการกำหนดความถี่ของเวลาเอง เราสามารถใช้ endpoints() คู่กับ period.apply() ได้

    โดย endpoints() ต้องการ input 3 อย่าง:

    1. x: time series data
    2. on: ระดับช่วงเวลา (เช่น ปี, เดือน, สัปดาห์)
    3. k: จำนวน

    และ period.apply() ต้องการ input 3 อย่าง คือ:

    1. x: time series data
    2. INDEX: variable ที่เก็บ endpoints() เอาไว้
    3. FUN: function ที่ใช้สรุปข้อมูล (เช่น mean())

    ยกตัวอย่างเช่น เราต้องการหาค่าเฉลี่ยราคาปิด Bitcoin ทุก ๆ 3 เดือน เราจะเขียนภาษา R ได้แบบนี้:

    # Create 3-month interval
    three_month_eps <- endpoints(x = btc_zoo,
                                 on = "months",
                                 k = 3)
    
    # Apply the interval
    btc_three_month_data <- period.apply(x = btc_zoo[, "close"],
                                         INDEX = three_month_eps,
                                         FUN = mean)
    
    # Plot the results
    autoplot.zoo(btc_three_month_data) +  
      
      ## Adjust line colour
      geom_line(color = "blue") +
      
      ## Add title and labels
      labs(title = "Bitcoin 3-Month Average Closing Price (2010–2024)",
           x = "Date",
           y = "Closing Price (USD)") +
      
      ## Use minimal theme
      theme_minimal()
    

    ผลลัพธ์:


    🪟 Rolling Window

    Rolling window (moving window หรือ sliding window) คือ การสรุปข้อมูลตามช่วงเวลาที่กำหนด โดยช่วงเวลาในการคำนวณจะเคลื่อนตัวไปเรื่อย ๆ

    เช่น เราต้องการหาค่าเฉลี่ยของราคาปิด Bitcoin ในช่วง 7 วันล่าสุด การใช้ rolling window จะทำให้เราได้ข้อมูลดังนี้:

    DateAverage
    2024-01-07ค่าเฉลี่ยระหว่างวันที่ 1 ถึง 7
    2024-01-08ค่าเฉลี่ยระหว่างวันที่ 2 ถึง 8
    2024-01-09ค่าเฉลี่ยระหว่างวันที่ 3 ถึง 9

    ในภาษา R เราสามารถสร้าง rolling window ได้ 2 วิธี:

    1. ใช้ roll*()
    2. ใช้ rollapply()

    .

    1️⃣ roll*()

    เราสามารถสร้าง rolling window ได้ด้วย roll*() จาก zoo package เช่น:

    FunctionDescription
    rollmean()หาค่าเฉลี่ย
    rollmedian()หาค่ากลาง
    rollmax()หาค่าสูงสุด
    rollsum()หาผลรวม

    roll*() ต้องการ input 3 อย่าง ได้แก่:

    1. x: time series data
    2. k: ช่วงเวลา (window)
    3. align: กำหนดว่า ค่าสรุปที่ได้จะอยู่ด้วยซ้าย ขวา หรือกลางช่วงเวลา
    4. fill: จะแทนค่า missing values หรือไม่

    ยกตัวอย่างเช่น เราต้องการหาค่าเฉลี่ยราคาปิด Bitcoin ในช่วง 30 วัน เราจะใช้ rollmean() แบบนี้:

    # Create the window for mean price
    btc_30_days_roll_mean <- rollmean(x = btc_zoo,
                                      k = 30,
                                      align = "right",
                                      fill = NA)
    
    # Plot the results
    autoplot.zoo(btc_30_days_roll_mean[, "close"]) +  
      
      ## Adjust line colour
      geom_line(color = "blue") +
      
      ## Add title and labels
      labs(title = "Bitcoin 30-Day Rolling Mean Price (2010–2024)",
           x = "Time",
           y = "Closing (USD)") +
      
      ## Use minimal theme
      theme_minimal()
    

    ผลลัพธ์:

    .

    2️⃣ rollapply()

    ในกรณีที่เราต้องการกำหนดการสรุปข้อมูลใน rolling window (เช่น หาค่าต่ำสุด ซึ่งไม่มีใน zoo package) เราสามารถทำได้ด้วย rollapply() ซึ่งต้องการ input 4 อย่างดังนี้:

    1. data: time series data
    2. width: ช่วงเวลา (window)
    3. FUN: การสรุปข้อมูล (เช่น min)
    4. align: กำหนดว่า ค่าสรุปที่ได้จะอยู่ด้วยซ้าย ขวา หรือกลางช่วงเวลา
    5. fill: จะแทนค่า missing values หรือไม่

    ยกตัวอย่างเช่น หาราคาปิดต่ำสุดของทุก ๆ 30 วัน:

    # Creating a rolling window with min() function
    btc_30_days_roll_min <- rollapply(data = btc_zoo,
                                      width = 30,
                                      FUN = min,
                                      align = "right",
                                      fill = NA)
    
    # Plot the results
    autoplot.zoo(btc_30_days_roll_min[, "close"]) +  
      
      ## Adjust line colour
      geom_line(color = "blue") +
      
      ## Add title and labels
      labs(title = "Bitcoin 30-Day Rolling Minimum Price (2010–2024)",
           x = "Time",
           y = "Closing (USD)") +
      
      ## Use minimal theme
      theme_minimal()
    

    ผลลัพธ์:


    ➡️ Expanding Window

    Expanding window เป็นการสรุปข้อมูลแบบสะสม เช่น:

    DateAverage
    2024-01-01หาค่าเฉลี่ยของวันที่ 1
    2024-01-02หาค่าเฉลี่ยของวันที่ 1 + 2
    2024-01-03หาค่าเฉลี่ยของวันที่ 1 + 2 + 3
    2024-01-04หาค่าเฉลี่ยของวันที่ 1 + 2 + 3 + 4
    2024-01-05หาค่าเฉลี่ยของวันที่ 1 + 2 + 3 + 4 + 5

    ในภาษา R เราสามารถสร้าง expanding window ได้ด้วย rollapply() โดยเราต้องกำหนดให้:

    1. width เป็นชุดตัวเลข (เช่น 1, 2, 3, …)
    2. align = "right" เสมอ

    ยกตัวอย่างเช่น สร้าง expanding window แบบค่าเฉลี่ยราคาปิดของเดือนมกราคม 2024:

    # Subset for Jan 2024 data
    btc_jan_2024 <- window(x = btc_zoo,
                           start = as.Date("2024-01-01"),
                           end = as.Date("2024-01-31"))
    
    # Create a sequence of widths
    btc_jan_2024_width <- seq_along(btc_jan_2024)
    
    # Create an expanding window for mean price
    btc_exp_mean <- rollapply(data = btc_2024,
                              width = btc_jan_2024_width,
                              FUN = mean,
                              align = "right",
                              fill = NA)
    
    # Plot the results
    autoplot.zoo(btc_exp_mean[, "close"]) +  
      
      ## Adjust line colour
      geom_line(color = "blue") +
      
      ## Add title and labels
      labs(title = "Bitcoin Expanding Mean Price (Jan 2024)",
           x = "Time",
           y = "Closing (USD)") +
      
      ## Use minimal theme
      theme_minimal()
    

    ผลลัพธ์:


    😎 Summary

    ในบทความนี้ เราได้ทำความรู้จักกับ 7 วิธีการทำงานกับ time series ในภาษา R โดยใช้ base R, lubridate, และ zoo package กัน:

    วิธีการทำงาน 1. Converting:

    FunctionFor
    as.Date()แปลง character เป็น Date
    as_date()แปลง character เป็น Date
    zoo()แปลง data frame เป็น zoo

    วิธีการทำงาน #2. Missing values:

    FunctionFor
    na.fill()แทนค่า missing values ด้วยค่าที่กำหนด
    na.locf()แทนค่า missing values ตามค่าของข้อมูลที่มาก่อนหน้า
    na.approx()แทนค่า missing values ด้วยการวิเคราะห์ข้อมูลที่มาก่อนและหลัง missing values

    วิธีการทำงาน #3. Plotting:

    FunctionFor
    autoplot.zoo()สร้างกราฟจาก zoo

    วิธีการทำงาน #4. Subsetting:

    FunctionFor
    window()ดึงข้อมูลช่วงเวลาที่ต้องการ
    btc_zoo[boolean_mask, ]ดึงข้อมูลช่วงเวลาที่ต้องการ
    btx_zoo[x, y]ดึงข้อมูลวันที่ต้องการ

    วิธีการทำงาน #5. Aggregating:

    FunctionFor
    apply.daily()สรุปข้อมูลรายวัน
    apply.weekly()สรุปข้อมูลรายสัปดาห์
    apply.quarterly()สรุปข้อมูลรายไตรมาส
    apply.yearly()สรุปข้อมูลรายปี
    endpoints() และ period.apply()สรุปข้อมูลตามช่วงเวลาที่กำหนดเอง

    วิธีการทำงาน #6. Rolling window:

    FunctionFor
    rollmean()rolling window แบบหาค่าเฉลี่ย
    rollmedian()rolling window แบบหาค่ากลาง
    rollmax()rolling window แบบหาค่าสูงสุด
    rollsum()rolling window แบบหาผลรวม
    rollapply()rolling window แบบกำหนดการสรุปข้อมูลเอง

    วิธีการทำงาน #7. Expanding window:

    FunctionFor
    seq_along() และ rollapply()สร้าง expanding window

    😺 View Code in GitHub

    ดู code และ dataset ในบทความนี้ได้ที่ GitHub


    📃 References


    ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    📕 ขอฝากหนังสือเล่มแรกในชีวิตด้วยนะครับ 😆

    🙋 ใครที่กำลังเรียนจิตวิทยาหรือทำงานสายจิตวิทยา และเบื่อที่ต้องใช้ software ราคาแพงอย่าง SPSS และ Excel เพื่อทำข้อมูล

    💪 ผมขอแนะนำ R Book for Psychologists หนังสือสอนใช้ภาษา R เพื่อการวิเคราะห์ข้อมูลทางจิตวิทยา ที่เขียนมาเพื่อนักจิตวิทยาที่ไม่เคยมีประสบการณ์เขียน code มาก่อน

    ในหนังสือ เราจะปูพื้นฐานภาษา R และพาไปดูวิธีวิเคราะห์สถิติที่ใช้บ่อยกัน เช่น:

    • Correlation
    • t-tests
    • ANOVA
    • Reliability
    • Factor analysis

    🚀 เมื่ออ่านและทำตามตัวอย่างใน R Book for Psychologists ทุกคนจะไม่ต้องพึง SPSS และ Excel ในการทำงานอีกต่อไป และสามารถวิเคราะห์ข้อมูลด้วยตัวเองได้ด้วยความมั่นใจ

    แล้วทุกคนจะแปลกใจว่า ทำไมภาษา R ง่ายขนาดนี้ 🙂‍↕️

    👉 สนใจดูรายละเอียดหนังสือได้ที่ meb: