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:

Comments

Leave a comment