Introduction

這份文件會簡單走一遍 EDA 的流程,並根據我們在作業一看到的問題給一些小建議,我們示範的 dataset 是來自政府資料開放平台的 火車每日各站點進出站人數

EDA 的目標是要對資料有更進一步的認識,除了最基本的理解資料框各欄位的意義,我們還可以利用簡單的視覺化觀察各欄位資料的分布,再來進一步分析各變數是否有潛在的相關性

Code

第一步: 讀取資料

大家取得資料集的來源不盡相同,尤其有些人的資料集內可能會有中文資料,然而 R 對於非英文資料的處理有些不友善,這邊提供一個原則性的方法來預處理並讀取資料,基本上可以解決大多狀況。如果只是純英文資料可以直接進入讀取的部分。

  1. 確保資料編碼(encoding)儲存為 utf8(UTF-8)

    可以直接使用 RStudio 開啟原始的 csv 檔,然後左上角選 Save with Encoding… -> UTF-8。

  2. 使用 readr 套件裡的 read_csv,可以解決原生的 read.csv 會遇到的許多莫名其妙的問題。

    library(readr)
    raw_data <- read_csv("每日各站進出站人數2018.csv")
    ## Parsed with column specification:
    ## cols(
    ##   BOARD_DATE = col_double(),
    ##   TKT_BEG = col_double(),
    ##   STOP_NAME = col_character(),
    ##   進站 = col_double(),
    ##   出站 = col_double()
    ## )

    如果不想只為了使用一次而引入整個套件,可以改成

    raw_data <- readr::read_csv("每日各站進出站人數2018.csv")

第二步: 初步認識資料結構

通常在下載資料的網站都會有介紹各個欄位所代表的意義,我們仍然可以使用 str, head, View 等函數來觀察我們讀進來的資料。

  • str 會提供資料行列數,並簡介資料內的各個 column ,包含名稱、變數型別(數字、文字)。

    str(raw_data)
    ## Classes 'spec_tbl_df', 'tbl_df', 'tbl' and 'data.frame': 83054 obs. of  5 variables:
    ##  $ BOARD_DATE: num  20180101 20180101 20180101 20180101 20180101 ...
    ##  $ TKT_BEG   : num  4 6 8 9 10 12 14 15 18 20 ...
    ##  $ STOP_NAME : chr  "台東" "山里" "鹿野" "瑞源" ...
    ##  $ 進站      : num  13685 7 356 43 7 ...
    ##  $ 出站      : num  7623 11 184 25 4 ...
    ##  - attr(*, "spec")=
    ##   .. cols(
    ##   ..   BOARD_DATE = col_double(),
    ##   ..   TKT_BEG = col_double(),
    ##   ..   STOP_NAME = col_character(),
    ##   ..   進站 = col_double(),
    ##   ..   出站 = col_double()
    ##   .. )
    這裡可以看到我們的資料一共有5個欄位、83054筆紀錄,其中四個欄位是數值,一個欄位是文字。
    另外從資料來源網站可以看到每個欄位分別代表
    • BOARD_DATE: 該筆資料日期
    • TKT_BEG: 該筆資料代表車站的編號
    • STOP_NAME: 該筆資料代表車站的站名
    • 進站: 該日該車站的進站人數
    • 出站: 該日該車站的出站人數
  • head 會取出資料的前六列,讓你可以快速瀏覽資料框的樣子,避免把整個太大的資料框全部顯示出來

    head(raw_data)
    ## # A tibble: 6 x 5
    ##   BOARD_DATE TKT_BEG STOP_NAME  進站  出站
    ##        <dbl>   <dbl> <chr>     <dbl> <dbl>
    ## 1   20180101       4 台東      13685  7623
    ## 2   20180101       6 山里          7    11
    ## 3   20180101       8 鹿野        356   184
    ## 4   20180101       9 瑞源         43    25
    ## 5   20180101      10 瑞和          7     4
    ## 6   20180101      12 關山        950   528

    也可以多加一個參數指定要取出前幾行

    head(raw_data, 10)
    ## # A tibble: 10 x 5
    ##    BOARD_DATE TKT_BEG STOP_NAME  進站  出站
    ##         <dbl>   <dbl> <chr>     <dbl> <dbl>
    ##  1   20180101       4 台東      13685  7623
    ##  2   20180101       6 山里          7    11
    ##  3   20180101       8 鹿野        356   184
    ##  4   20180101       9 瑞源         43    25
    ##  5   20180101      10 瑞和          7     4
    ##  6   20180101      12 關山        950   528
    ##  7   20180101      14 海端          7     2
    ##  8   20180101      15 池上        907   471
    ##  9   20180101      18 富里        319   183
    ## 10   20180101      20 東竹          8    14

    或是使用 tail 觀察最後幾行

    tail(raw_data)
    ## # A tibble: 6 x 5
    ##   BOARD_DATE TKT_BEG STOP_NAME  進站  出站
    ##        <dbl>   <dbl> <chr>     <dbl> <dbl>
    ## 1   20181231     333 美術館      854   813
    ## 2   20181231     334 鼓山        239   215
    ## 3   20181231     336 三塊厝      364   359
    ## 4   20181231     337 民族        559   495
    ## 5   20181231     338 科工        882   886
    ## 6   20181231     339 正義       1167   914
  • View 通常不會使用在 Rmd,而是我們在寫 RScript 的時候可以打開一個新視窗來用表格的型式檢視資料框。

    View(raw_data)

第三步: 找出有興趣或有潛在關係的變數畫圖觀察(同時根據我們想要做到的目標整理一下資料框)

在了解每個欄位所代表的意義後,我們便可以嘗試視覺化一些結果 先引入一些重要的套件:

library(dplyr)
library(tidyr)
library(ggplot2)

簡單的處理

  1. 重新命名各欄位

    data <- raw_data %>%
        rename(Date=BOARD_DATE, StopID=TKT_BEG, StopName=STOP_NAME, In="進站", Out="出站")
    
    head(data)
    ## # A tibble: 6 x 5
    ##       Date StopID StopName    In   Out
    ##      <dbl>  <dbl> <chr>    <dbl> <dbl>
    ## 1 20180101      4 台東     13685  7623
    ## 2 20180101      6 山里         7    11
    ## 3 20180101      8 鹿野       356   184
    ## 4 20180101      9 瑞源        43    25
    ## 5 20180101     10 瑞和         7     4
    ## 6 20180101     12 關山       950   528
  2. 將日期分割成年月日三個欄位。
    (利用 select(-Date) 可以移除 Date 這個 column)
    (這份資料的日期是很乾淨的8位數字,因此可以用一些簡單的數學計算找出年月日,如果需要更進階的日期處理,可以學習 lubridate 這個套件)

    data <- data %>%
        mutate(year=Date%/%10000, month=(Date%/%100)%%100, day=Date%%100) %>%
        select(-Date)
    
    head(data)
    ## # A tibble: 6 x 7
    ##   StopID StopName    In   Out  year month   day
    ##    <dbl> <chr>    <dbl> <dbl> <dbl> <dbl> <dbl>
    ## 1      4 台東     13685  7623  2018     1     1
    ## 2      6 山里         7    11  2018     1     1
    ## 3      8 鹿野       356   184  2018     1     1
    ## 4      9 瑞源        43    25  2018     1     1
    ## 5     10 瑞和         7     4  2018     1     1
    ## 6     12 關山       950   528  2018     1     1
  3. 我們可以利用 group_by(StopID) 先挑選出總流量最大的幾個大站並繪圖

    data_by_stop <- data %>%
        group_by(StopID, StopName) %>%
        summarise(In=sum(In), Out=sum(Out)) %>%
        ungroup
    
    top10Stops <-  top_n(data_by_stop, 10, In)$StopName
    top10Stops
    ##  [1] "松山" "台北" "板橋" "樹林" "桃園" "中壢" "新竹" "台中" "台南" "高雄"
    data_by_stop %>%
        filter(StopName %in% top10Stops) %>%
        gather("InOut", "count", In:Out) %>%
        ggplot(aes(x=StopName, y=count, fill=InOut)) + 
        geom_bar(stat="identity", position="dodge") + 
        ggtitle("前十大車站流量長條圖")

  4. 接下來也可以利用 groupt_by(month) 來看每個月的旅客流量

    data_by_month <- data %>%
        group_by(month, StopName) %>%
        summarise(In=sum(In), Out=sum(Out)) %>%
        ungroup
    
    data_by_month %>%
        filter(StopName %in% top10Stops) %>%
        ggplot(aes(x=month, y=In, color=StopName)) + 
        geom_line() + 
        ggtitle("2018年前十大車站各月流量(進站)折線圖") +
        scale_x_continuous(breaks=1:12)

到這邊為止,我們已經利用簡單的視覺化對資料有了基本的認識。

EDA 之後…

透過以上的簡單資料處理及視覺化,我們已經對資料集有一些初步認識,這時候你可能對這份資料有一些猜測,例如:哪些月份流量特別大?為什麼? 為了解決這些問題我們可能需要找到更多的資料來做參考,並利用一些統計的方式來驗證自己的假設。
在第一、二份作業,我們希望大家加強處理資料和利用視覺化來做 EDA 的能力,來從各式各樣的資料集中找出潛在的各種分析方向。