1 of 31

Read tabulated�.csv and summarizing data

Taipei theft data and pivot analysis

2 of 31

Data and goal

3 of 31

The data and goal

Summarizing

(Pivot analysis)

Raw data: records

Group by region and time

Plotting

4 of 31

資料的紀錄形式:點位資料

觀察值、點位資料:公部門所發布的開放資料通常會根據某些類別進行統計,例如年齡、性別、教育程度、地區等等,只有少部分的資料會用觀察值(Observation)的方式來記錄,也就是每一個案例紀錄一筆資料。

例如疫情一開始人數還少的時候,會逐一記錄每個個案;地理資訊系統上面記錄某些機構或某些特定地點的時候也是點位資料;或在觀察輿情時,每筆發言或留言都是一筆觀察值。「臺北市住宅竊盜點位資訊」就是逐案紀錄的點位資料。而以下的例子也是點位資料,主要為主要為噪音、竊盜、交通事故等相關點位資料。

5 of 31

交通事故點位資料

6 of 31

資料型態(如何被儲存)�What is CSV?

CSV是逗點分隔檔案,也可以是TAB分隔(.tsv檔),或者是「;」分隔。特色是不管資料內容如何,都必須被框架在二維的表格裡,xls或xlsx等Excel檔案或者google sheet檔案,都可說是這類格式的資料。標準的CSV檔案表示方法如同下方的紫外線資料。大約可以看見是個二維表格的樣子

資料內容必須記錄資料變項名稱與資料值。第一列為變項名稱,以逗點分隔。在每列的最末還有一個隱藏字元\n,其為換行符號。通常CSV檔案打開就是如以下為七個欄位的資料,一共有五筆資料。�SiteName,UVI,PublishAgency,County,WGS84Lon,WGS84Lat,PublishTime\n�花蓮,5.59,中央氣象局,花蓮縣,"121,36,48","23,58,30",2015-11-23 12:00\n�馬祖,4.49,中央氣象局,連江縣,"119,55,24","26,10,09",2015-11-23 12:00\n�高雄,4.39,中央氣象局,高雄市,"120,18,57","22,33,58",2015-11-23 12:00\n�玉山,8.14,中央氣象局,南投縣,"120,57,34","23,29,15",2015-11-23 12:00\n�臺南,4.45,中央氣象局,臺南市,"120,12,17","22,59,36",2015-11-23 12:00\n

CSV

(comma separated value)

7 of 31

Pivot analysis (Summarizing by group)

將紀錄資料,依照某些變項分組做計次

  • 有台南市登革熱通報資料,依區名計算每區各有多少例
  • 有PTT貼文,依作者與時間(每小時)計算發文數量

將某(連續)變項,依照某些類別變項分組求取每組的�總和、平均、或標準差

  • 依照性別或教育程度求取分組平均薪資
  • 彙整鄉鎮內的村里人口數作為鄉鎮人口數

計次、計算某些類別各有幾筆資料

��摘要、彙整。計算某些類別中數值的總和、平均、標準差

大學

38,000

高中

42,000

大學

39,000

大學

38,000

中西區

XX村

中西區

YY村

南區

XX里

南區

XX村

8 of 31

You will learn ...

What is CSV and How to read it into R? read.csv()�(Note) How to avoid converting textual data to factor type? stringsAsFactor=FALSE

Inspecting variables to selecting and filtering data�Summarizing each variable by table(), tapply(), and dplyr::count()

Pivot analysis (summarization) on two variables ? �by table(), tapply(), and dplyr::count()

Plotting�(Note) color, chinese font, substr()

mutate new variables

Read csv

Filter rows by column value

Plotting

Count (Pivot)

9 of 31

Reading CSV:

Taipei theft

10 of 31

The data

台北住宅竊盜點位資訊�http://data.taipei/opendata/datalist/datasetMeta?oid=68785231-d6c5-47a1-b001-77eec70bec02

分析上,我建立一個簡單的假設是,我認為在不同行政區不同時段發生次數會有所差別。

11 of 31

I. Reading TP theft data (CSV)

url <- "http://data.taipei/opendata/datalist/datasetMeta/download?id=68785231-d6c5-47a1-b001-77eec70bec02&rid=34a4a431-f04d-474a-8e72-8d3f586db3df"��df <- read.csv(url, fileEncoding = "big5")

# OR, reading the data pre-saving in the data folder

# df <- read.csv("data/tp_theft.csv", fileEncoding = "big5")

12 of 31

II. Observing data

head(df) 編號 案類 發生.現.日期 發生時段 發生.現.地點�1 1 住宅竊盜 780210 10~12 台北市中山區新生北路3段31 ~ 60號�2 2 住宅竊盜 951016 19~21 台北市信義區三張里莊敬路341巷1 ~ 30號�3 3 住宅竊盜 970609 01~03 台北市信義區松隆里松山路615巷1 ~ 30號�..class(df)[1] "data.frame"summary(df) 編號 案類 發生.現.日期 發生時段 發生.現.地點 � Min. : 1 住宅竊盜:1837 Min. : 780210 10~12 :323 台北市中正區螢雪里詔安街61 ~ 90號 : 7 � 1st Qu.: 460 1st Qu.:1040920 13~15 :254 台北市萬華區富民路91~120號 : 5 � Median : 919 Median :1050605 19~21 :250 台北市北投區東華里立農街2段151 ~ 180號: 4 � Mean : 919 Mean :1049610 22~24 :242 台北市萬華區青年路31~60號 : 4 � 3rd Qu.:1378 3rd Qu.:1060221 07~09 :232 台北市中山區林森北路391~420號 : 4

13 of 31

II. Observing data structure

str(df)'data.frame': 1837 obs. of 5 variables:� $ 編號 : int 1 2 3 4 5 6 7 8 9 10 ...� $ 案類 : Factor w/ 1 level "住宅竊盜": 1 1 1 1 1 1 1 1 1 1 ...� $ 發生.現.日期: int 780210 951016 970609 990407 991013 991024 991116 1000101 1000825 1001116 ...� $ 發生時段 : Factor w/ 8 levels "01~03","04~06",..: 4 7 1 2 8 5 8 4 7 7 ...� $ 發生.現.地點: Factor w/ 1700 levels "台北市北投區八仙里承德路7段401巷1111 ~ 1140號",..: 1535 1310 1320 1077 520 437 1318 268 369 1206 ...

> class(df$發生.現.日期)[1] "integer"

> class(df$發生時段)[1] "factor"

> class(df$發生.現.地點)[1] "factor"

14 of 31

Avoid factor type variables

為何會出現factor是因為在用read.csv()讀取該資料檔時,預設將文字型態的資料轉變為Nominal變項,也就是視為factor來處理。但R可以處理一般文字,不建議轉為factor。可以用下列兩種方式來解決��Method 1 在讀取資料時增加參數stringsAsFactors,指定文字不要自動被轉為factor�df <- read.csv(url, fileEncoding = "big5", stringsAsFactors = FALSE)�Method 2 將該參數設定為全域參數,任何讀檔有此參數者,全部不要轉為factor�options(stringsAsFactors = FALSE)

MORE 後續的統計分析偶而會需要先把類別資料轉為factor才可以做分析

15 of 31

III. Selecting data, converting variables

避免中文作為變數名稱

篩選出所需要的資料:例如月份、年份、時間區間、縣市、鄉鎮市區

16 of 31

III. Selecting data, converting variables

# Get substring of var "發生時段" and assign to a new time var

df$time <- df$發生時段

df$county <- substr(df$發生.現.地點, 1, 3)

# Get substring of var "發生.現.地點" and assign to a new region var

df$region <- substr(df$發生.現.地點, 4, 5)

17 of 31

Pivot analysis

數值分佈是否正常?�或者有些有趣之處?

是否有Outlier, irrelevant data

18 of 31

IV. Pivot analysis for filtering data

觀察每個變項的數值是否正常、是否有異常值(Outlier)、是否為與分析目無關之資料(irrelevant data)

# counting the frequency of time variabletable(df$time)

# counting the frequency of region variabletable(df$region)

19 of 31

Method 1. table() to count by single variable

table(df$time)

01 04 07 10 13 16 19 22

167 173 232 384 254 281 250 281

table(df$region)�中山 中正 信義 內湖 北投 南港 士林 大同 大安 文山 松山 萬華

256 151 130 197 212 102 227 107 176 136 141 187

20 of 31

Method 2. tapply() to count by single variable

tapply(df$編號, df$time, length)� 01 04 07 10 13 16 19 22 �143 122 205 278 224 194 224 209

��tapply(df$編號, df$region, length)�北投 大安 大同 南港 內湖 士林 松山 萬華 文山 信義 中山 中正 163 136 80 69 162 179 115 143 110 104 218 120

21 of 31

V. Filtering data

df <- df[!df$time %in% c("00~03", "06~09", "09~12", "12~15", ]

df <- df[!df$region %in% c("三重","中和","淡水","板橋"), ]

df1 <- df[ , ]

Filter �rows

Select cols

22 of 31

VI. Pivot analysis on 2 vars

Method 1. Count two variables by table()

res_table <- table(df$time, df$region)

class(res_table) # [1] "table"

res_table

中山 中正 信義 內湖 北投 南港 士林 大同 大安 文山 松山 萬華

01 27 12 10 11 21 7 27 12 8 11 8 13

04 22 11 12 20 19 7 15 15 12 10 7 23

07 30 17 12 25 16 17 20 15 22 17 18 23

10 37 30 18 37 43 20 37 16 45 27 40 34

13 23 13 17 31 35 10 34 16 26 15 15 19

16 23 22 15 25 44 14 34 14 29 17 17 27

19 36 20 18 23 15 13 35 10 15 14 22 29

22 58 26 28 25 19 14 25 9 19 25 14 19

23 of 31

VI. Pivot analysis on 2 vars

Method 2. Count two variables by tapply()

res_tapply <- tapply(df$編號, list(df$time, df$region), length)

class(res_tapply) # [1] "matrix"

res_tapply

中山 中正 信義 內湖 北投 南港 士林 大同 大安 文山 松山 萬華

01 27 12 10 11 21 7 27 12 8 11 8 13

04 22 11 12 20 19 7 15 15 12 10 7 23

07 30 17 12 25 16 17 20 15 22 17 18 23

10 37 30 18 37 43 20 37 16 45 27 40 34

13 23 13 17 31 35 10 34 16 26 15 15 19

16 23 22 15 25 44 14 34 14 29 17 17 27

19 36 20 18 23 15 13 35 10 15 14 22 29

22 58 26 28 25 19 14 25 9 19 25 14 19

24 of 31

VI. Pivot analysis on 2 vars

Method 3. Count two variables by dplyr::count()

res_count <- dplyr::count(df, time, region)

res_count

# spreading the region into columns

res_count_spread <- tidyr::spread(res_count, region, n, fill = 0)

res_count_spread

25 of 31

VII. Plotting

26 of 31

Plotting

par(family=('STKaiti'))�mosaicplot(res_table)

27 of 31

mosaicplot() �using self-defined color

par(family=('Heiti TC Light')) # 引入中文字型蘋果黑體�par(family=('STKaiti')) # 引入中文字型標楷體��colors <- c('#D0104C','#DB4D6D','#E83015','#F75C2F', '#E79460','#E98B2A','#9B6E23','#F7C242','#BEC23F', �'#90B44B', '#66BAB7', '#1E88A8')

mosaicplot(res, color=colors, border=0, off = 3, �main="Theft rate")

library(RColorBrewer) # 使用RColorBrewer套件設定顏色�pcolor <- brewer.pal(12, "Paired")�mosaicplot(res, color=pcolor, border=0, off = 3, main="Theft rate of Taipei city (region by hour)")�

28 of 31

Review

29 of 31

2

22

內湖

3

13

南港

4

22

內湖

5

22

大安

6

13

南港

7

21

大安

8

07

南港

9

21

大安

22

內湖

2

13

南港

2

22

大安

1

21

大安

2

07

南港

1

內湖

南港

大安

22

2

0

1

13

0

2

0

21

0

0

2

07

0

1

0

Events

Long-table (tidyform)

Wide-table

aggregate(), count()

tapply(), table()

tidyr::spread()

tidyr::gather()

事件觀察紀錄

統計常見資料格式,每一個Col恰是一個Variable,便於做統計分析�

tidy form

資料末端消費者常見格式,例如見報的資料或報表等。

30 of 31

Review: Data Summarization

tapply()�> res <- tapply(df$編號, list(df$time, df$region), length)�> class(res)�[1] "matrix"

table()�> t <- table(df$time, df$region)�> class(t)�[1] "table"

aggregate() + spread()> res3 <- aggregate(df$編號, by=list(df$time, df$region), length)�> res4 <- tidyr::spread(res3, Group.2, x, fill = 0)�> class(res3)�[1] "data.frame"

count() + spread()> res5 <- dplyr::count(df, time, region)�> res6 <- tidyr::spread(res5, region, n, fill = 0)

31 of 31

Review: Read CSV

# read.csv用以將CSV檔轉為R的物件格式。CSV本身就是二維表格的結構,若無編碼問題會直接轉為data.frame。

# read.csv一共有四種不同函式,若read.csv()不成可試試read_csv()�utls::read.csv() # 隨base pkg載入的�utls::read.csv2() # 隨base載入,用以讀;分號分隔檔案�readr::read_csv() # readr pkg的函式�readr::read_csv2() # readr的函式,用以讀分號分隔檔案

# read.csv()可以直接讀一個已經被載入到電腦的資料,也可以直接讀url上的資料。�df <- read.csv("data/tp_theft.csv", fileEncoding = "big5")�url <- "http://data.taipei/opendata/datalist/datasetMeta/download?id=68785231-d6c5-47a1-b001-77eec70bec02&rid=34a4a431-f04d-474a-8e72-8d3f586db3df"�df <- read.csv(url, fileEncoding = "big5")

# read.csv()需要注意他的編碼和是否記得把stringsAsFactor設為FALSE,通常只有中文才會需要注意資料原始檔案是否為big5編碼options(stringsAsFactors = F)