2018年11月18日 星期日

經營管理講座 - Big Data Application

# Big data
# R
# package
# leaflet

主題: Big Data Application
日期: 2018.11.19
地點: 育達科技大學碩士班經營管理講座




2018年10月27日 星期六

主題式地圖(Thematic map) - 政府開放資料為例


# 主題式地圖
# Thematic map
# 開放式資料
# open data
# 地圖資料與社會經濟資料合併
# rgdal 套件
# tmap 套件

2022.7.28 更新R程式碼

# end

主題
本例說明考量社會經濟等開放式資料,輔以主題式繪圖方式,提升資料視覺化品質,便於資料呈現與溝通。下載資料的儲存目錄以C:\rdata為主。本範例包括以下六大步驟:

步驟1:下載社會經濟開放資料
步驟2:下載地圖資料
步驟3:匯入地圖資料至R
步驟4:匯入臺北市住宅竊盜點位資訊資料
步驟5:將臺北市住宅竊盜點位資訊整合至twn.taipei@data
步驟6:臺北市住宅竊盜分佈圖

步驟1:下載社會經濟開放資料

本例以臺北市住宅竊盜點位資訊為例,資料筆數;1945,欄位個數:5,欄位名稱:編號,案類,發生(現)日期,發生時段,發生(現)地點。下載檔案:「臺北市10401-10709住宅竊盜點位資訊.csv」 。

下載網址:https://data.gov.tw/dataset/73886,參考圖-1,圖-2說明。


















圖1-開放資料-臺北市住宅竊盜點位資訊


圖2-臺北市住宅竊盜點位資訊CSV檔案

目前資料集已經下架, 請參考以下網址直接下載:

步驟2:下載地圖資料

參考政府資料開放平台,常用的地理資料包括下列二個項目:

1. 鄉鎮市區界線(TWD97經緯度),資料包括鄉(鎮、市、區)行政區域界線圖資。

下載網址:https://data.gov.tw/dataset/7441,參考圖-3說明。


圖3-鄉鎮市區界線下載

2. 直轄市、縣市界線(TWD97經緯度),資料包括直轄市以及縣(市)行政區域界線圖資

下載網址:https://data.gov.tw/dataset/7442,參考圖-4說明。

圖4-直轄市、縣市界線下載

本例考量分析台北市各區資料,因此下載第一項「 鄉鎮市區界線(TWD97經緯度)」,下載檔案為「 mapdata201805311056.zip」,解壓縮為「C:\rdata\mapdata201805311056」資料夾,參考圖-5說明。

地圖資料包括 .shp, .shx, .dbf, .prj,其中shp, shx, dbf 為三個必備檔案:
  • .shp:圖形格式,用於儲存地圖元素的幾何資料。
  • .shx:— 圖形索引格式,即幾何資料索引。記錄每一個幾何資料shp檔案之中的位置,能夠加快向前或向後搜尋幾何資料的效率。
  • .dbf:屬性資料格式,以dBase IV的資料表格式儲存每個幾何形狀的屬性資料。
  • .prj:圖形格式.shp檔案中幾何資料所使用的經緯度座標系統。


圖5-鄉鎮市區界線(TWD97經緯度)解壓資料夾

步驟3:匯入地圖資料至R

使用 rgdal 套件的 readOGR函數 以匯入地圖資料,使用 tmap 套件以製作主題式地圖

library(rgdal)
library(tmap)

# 匯入地理資料 readOGR {rgdal}
twn <- readOGR(dsn="C:/rdata/mapdata201805311056", layer="TOWN_MOI_1070516", encoding="UTF-8")
head(twn@data) # 中文亂碼

# 中文亂碼轉換 iconv {base}
twn@data$COUNTYNAME <- iconv(twn@data$COUNTYNAME, from = "UTF-8", to="UTF-8")
twn@data$TOWNNAME <- iconv(twn@data$TOWNNAME, from = "UTF-8", to="UTF-8")
head(twn@data) # 中文正常顯示

names(attributes(twn)) # 7個屬性
summary(twn) # 資料摘要
names(twn) # 7個欄位
class(twn) # SpatialPolygonsDataFrame
str(twn@data) # 368*7

# 篩選臺北市地理資料
twn.taipei <- twn[which(twn@data$COUNTYNAME == "臺北市"), ]
twn.taipei@data

str(twn.taipei@polygons[1])
str(twn.taipei@polygons[5])

步驟4:匯入臺北市住宅竊盜點位資訊資料

theft <- read.table("臺北市10401-10709住宅竊盜點位資訊.csv", header=TRUE, sep=",", stringsAsFactors=FALSE) # 2054*5

# 將發生.現.日期由民國年轉為西元年
theft$發生.現.日期 <- as.Date(unlist(lapply(theft$發生.現.日期, function(x) {
  if (nchar(x) == 6) return(paste0(as.numeric(substr(x,1,2))+1911, "-", substr(x,3,4), "-", substr(x,5,6)))
  if (nchar(x) == 7) return(paste0(as.numeric(substr(x,1,3))+1911, "-", substr(x,4,5), "-", substr(x,6,7)))
})))

# 新增行政區欄位
# substr 函數與 Excel =MID函數 類似, 取出部分字串
theft$行政區 <- substr(theft$發生.現.地點,4,6)

# 篩選2018年&台北市資料
theft.2018 <- theft[theft$發生.現.日期 >= as.Date("2018-01-01") &  substr(theft$發生.現.地點,1,3) == "台北市" ,] # 247*6

# 樞紐分析各行政區住宅竊盜次數小計
theaft.area <- aggregate(案類~行政區, data=theft.2018[c(2,6)], length)
names(theaft.area) <- c("行政區", "住宅竊盜發生數")
summary(theaft.area)

步驟5:將臺北市住宅竊盜點位資訊整合至twn.taipei@data

# merge函數中,sort參數須設定為FALSE,否則繪圖位置會有錯誤
twn.taipei@data <- merge(twn.taipei@data, theaft.area, by.x = "TOWNNAME", by.y = "行政區", sort=FALSE)
twn.taipei@data

步驟6:臺北市住宅竊盜分佈圖

# method 1 採用 plot{graphics}
住宅竊盜發生數.color <- cut(twn.taipei@data$住宅竊盜發生數,
                     breaks=c(0,10,15,20,30,Inf),
                     labels=c("10以下", "11~15", "16~20", "21~30", "31以上"))

# 建立彩色調色盤(color palette)
# 內建調色盤 rainbow, heat.colors, terrain.colors, topo.colors, cm.colors, 本例以heat.colors為主
twn.taipei@data$Col <- heat.colors(5)[as.numeric(住宅竊盜發生數.color)]

plot(twn.taipei, col=twn.taipei@data$Col, main="2018年臺北市住宅竊盜分佈圖")
text(coordinates(twn.taipei)[,1], coordinates(twn.taipei)[,2], twn.taipei$TOWNNAME, cex=0.7)
legend("topright", legend=levels(住宅竊盜發生數.color), fill=twn.taipei@data$Col, col= heat.colors(5), title="住宅竊盜發生數")

# method 2 採用 qtm{tmap}
qtm(shp=twn.taipei, fill="住宅竊盜發生數", text="TOWNNAME", fill.title="住宅竊盜發生數", title="2018年臺北市住宅竊盜分佈圖")


qtm(shp=twn.taipei, fill="住宅竊盜發生數", text="TOWNNAME", fill.title="住宅竊盜發生數", title="2018年臺北市住宅竊盜分佈圖", fill.palette="Blues")


qtm(shp=twn.taipei, fill="住宅竊盜發生數", text="TOWNNAME", fill.title="住宅竊盜發生數", title="2018年臺北市住宅竊盜分佈圖", fill.palette="Greens")

R程式碼 :
# title: 主題式地圖(Thematic map)-以政府開放資料為例
# date: 2018.10.28
# 本例說明考量社會經濟等開放式資料,輔以主題式繪圖方式,提升資料視覺化品質,使於資料呈現與溝通。

# 步驟1:
# 下載社會經濟等開放式資料,本例以臺北市住宅竊盜點位資訊為例,資料筆數;1945,欄位個數:5,欄位名稱:編號,案類,發生(現)日期,發生時段,發生(現)地點。
# 下載網址:https://data.gov.tw/dataset/73886

# 步驟2:下載地圖資料
# 本例考量分析台北市各區資料,因此下載第一項「 鄉鎮市區界線(TWD97經緯度)」,下載檔案為「 mapdata201805311056.zip」,解壓縮為「C:\rdata\mapdata201805311056」資料夾

# 下載世界地圖
# http://www.diva-gis.org/gdata


# 步驟3:匯入地圖資料至R
# 使用 rgdal 套件的 readOGR函數 以匯入地圖資料,使用 tmap 套件以製作主題式地圖

library(rgdal)
library(tmap)

# 匯入地理資料
twn <- readOGR(dsn="C:/rdata/mapdata201805311056", layer="TOWN_MOI_1070516", encoding="UTF-8")
head(twn@data) # 中文亂碼

# twn <- readOGR(dsn="C:/rdata/TWN_adm", layer="TWN_adm1", encoding="UTF-8")
head(twn@data) # 中文亂碼
names(twn@data)

# 中文亂碼轉換 iconv
twn@data$COUNTYNAME <- iconv(twn@data$COUNTYNAME, from = "UTF-8", to="UTF-8")
twn@data$TOWNNAME <- iconv(twn@data$TOWNNAME, from = "UTF-8", to="UTF-8")
head(twn@data) # 中文正常顯示

names(attributes(twn)) # 7個屬性
summary(twn) # 資料摘要
names(twn) # 7個欄位
class(twn) # SpatialPolygonsDataFrame
str(twn@data) # 368*7

# 篩選臺北市地理資料
twn.taipei <- twn[which(twn@data$COUNTYNAME == "臺北市"), ]
twn.taipei@data

str(twn.taipei@polygons[1])
str(twn.taipei@polygons[5])

# 步驟4:匯入臺北市住宅竊盜點位資訊資料
theft <- read.table("臺北市10401-10709住宅竊盜點位資訊.csv", header=TRUE, sep=",", stringsAsFactors=FALSE) # 2054*5

# 將發生.現.日期由民國年轉為西元年
theft$發生.現.日期 <- as.Date(unlist(lapply(theft$發生.現.日期, function(x) {
 if (nchar(x) == 6) return(paste0(as.numeric(substr(x,1,2))+1911, "-", substr(x,3,4), "-", substr(x,5,6)))
 if (nchar(x) == 7) return(paste0(as.numeric(substr(x,1,3))+1911, "-", substr(x,4,5), "-", substr(x,6,7)))
})))

# 新增行政區欄位
theft$行政區 <- substr(theft$發生.現.地點,4,6)

# 篩選2018年&台北市資料
theft.2018 <- theft[theft$發生.現.日期 >= as.Date("2018-01-01") & substr(theft$發生.現.地點,1,3) == "台北市" ,] # 247*6

# 樞紐分析各行政區住宅竊盜次數小計
theaft.area <- aggregate(案類~行政區, data=theft.2018[c(2,6)], length)
names(theaft.area) <- c("行政區", "住宅竊盜發生數")
summary(theaft.area)

# 步驟5:將臺北市住宅竊盜點位資訊資料整合至 twn.taipei@data
# merge函數中,sort參數須設定為FALSE,否則繪圖位置會有錯誤
twn.taipei@data <- merge(twn.taipei@data, theaft.area, by.x = "TOWNNAME", by.y = "行政區", sort=FALSE)
twn.taipei@data

# 步驟6:臺北市住宅竊盜分佈圖

# method 1 採用 plot{graphics}
住宅竊盜發生數.color <- cut(twn.taipei@data$住宅竊盜發生數, 
 breaks=c(0,10,15,20,30,Inf), 
 labels=c("10以下", "11~15", "16~20", "21~30", "31以上"))

# 建立彩色調色盤(color palette)
# 內建調色盤 rainbow, heat.colors, terrain.colors, topo.colors, cm.colors, 本例以heat.colors為主
twn.taipei@data$Col <- heat.colors(5)[as.numeric(住宅竊盜發生數.color)]

plot(twn.taipei, col=twn.taipei@data$Col, main="2018年臺北市住宅竊盜分佈圖")
text(coordinates(twn.taipei)[,1], coordinates(twn.taipei)[,2], twn.taipei$TOWNNAME, cex=0.7)
legend("topright", legend=levels(住宅竊盜發生數.color), fill=twn.taipei@data$Col, col= heat.colors(5), title="住宅竊盜發生數")

# method 2 採用 qtm{tmap}
qtm(shp=twn.taipei, fill="住宅竊盜發生數", text="TOWNNAME", fill.title="住宅竊盜發生數", title="2018年臺北市住宅竊盜分佈圖")

qtm(shp=twn.taipei, fill="住宅竊盜發生數", text="TOWNNAME", fill.title="住宅竊盜發生數", title="2018年臺北市住宅竊盜分佈圖", fill.palette="Blues")

qtm(shp=twn.taipei, fill="住宅竊盜發生數", text="TOWNNAME", fill.title="住宅竊盜發生數", title="2018年臺北市住宅竊盜分佈圖", fill.palette="Greens")
# end

2018年9月23日 星期日

2018人工智慧與資料科學應用研討會

2018人工智慧與資料科學應用研討會



主會議
2018 人工智慧與資料科學應用研討會
人工智慧與資料科學分析已成為萬眾矚目的焦點,每個領域都需要專精的分析人才,以及對商業有高度的敏銳度,找出企業問題協調組織面對,將能成為最有價值的企業人才。全球產官學界紛紛期盼能夠孵育頂尖人才,為了提升台灣在人工智慧的水準,本研討會邀請各界AI人工智慧與資料科學分析等專家齊聚一堂,為各位帶來AI與資料科學分析等一系列的專題演講,提供最近距離跟專家們會談。本研討會除了邀請專家學者進行精闢演說外,於研討會後翌日舉行Open data 分析競賽,促使AI技術與資料科學分析扎根於大專院校,提升高教學生在人工智慧技術與巨量資料分析的技能與優勢,更是學生學以致用的最佳發揮舞台。

競賽
2018 Open Data分析競賽
為推廣「人工智慧」與「資料科學」相關技術於開放資料(open data)的分析與應用,本競賽活動廣邀大專院校學生利用AI技術與資料科學分析進行創意發想與實作,用以培育人工智慧與資料科學分析之優秀大專院校學生。

研討會日期
2018年12月07日 - 2018年12月08日
主會議日期: 2018年12月07日
競賽日期: 2018年12月08日

研討會地點
東吳大學
台北市中正區貴陽街一段56號 (城中校區)

2018年9月2日 星期日

R程式除錯與效能提升設計

R程式除錯與效能提升設計

(Debug and performance improvements in R)


# R程式錯誤種類
# 除錯方法
# 除錯實務應用
# shiny除錯
# 效能提升

1. R程式錯誤種類

在1947年9月9日,葛麗絲·霍普(Grace Hopper)發現了第一個電腦上的bug。因此,人們逐漸開始用「Bug」(原意為「蟲子」)來稱呼電腦中的隱藏錯誤。即程式執行時,畫面顯示錯誤或整個程式沒反應,此時一般稱呼程式產生臭蟲(Bug),僅接著是找出臭蟲並進行錯誤修正,此步驟稱為除錯或偵錯(Debug),常見的程式錯誤包括以下四種情形,以下分別說明其內容。

(1)語法錯誤(Syntax Errors)
(2)編譯時期的錯誤(Compile Errors)
(3)執行時期錯誤(Run-time Errors)
(4)邏輯錯誤(Logical Errors)

1.1 語法錯誤
各種程式語言皆有其語法的規範,在撰寫程式過程中,如果程式不符合語法的規範,則會產生語法錯誤。語法錯誤可經由GUI編輯器,直接顯示錯誤訊息,例:R語言的免費GUI編輯器-RStudio(https://www.rstudio.com/products/RStudio/)。

例如:if 編輯if為IF,括號沒有成對使用,沒有先行匯入套件(Packages),結尾忘了加上「:」。

參考圖1 R語法錯誤,圖1上方 with bug 區塊中顯示語法錯誤「if 打成IF」,下方 complete debug 區塊中顯示已改為小寫if的正確結果。


圖1 R語法錯誤

1.2 編譯時期的錯誤
編譯時期的錯誤可以透過「編譯器(Compiler)」在編譯的時候就發現問題,較容易找出錯誤。

1.3 執行時期錯誤
執行時期的錯誤就比較難追蹤。例如:「 網路服務無法使用 」 的錯誤。二個數值相除,分母為零的錯誤,此階段可依據錯誤訊息而修正錯誤。緩衝區溢位(Buffer overflow)

1.4 邏輯錯誤
邏輯錯誤所造成的程式設計錯誤,例如,「 索引超出範圍 」 錯誤。使用者輸入不符合預期數值資料,例如,輸入英文字元。

程式錯誤情境中會有所謂例外(Exception),例外指的是程式發生不正常的錯誤,而導致無法繼續執行的情形。有的時候,僅管程式語法完全正確,當執行程式時仍然會有錯誤。這種在程式執行階段發生的錯誤亦稱為例外,並且會造成程式完全的終止且程式無法繼續執行。

2. 除錯方法

除錯的基本五大步驟:

2.1 發現程式錯誤的存在
在除錯前除了找出錯誤的現象,先備份原始程式碼或使用版本管理工具,亦是踏出基礎的原始碼管理的第一步。

2.2 小範圍逐步確認
以隔離、消除的方式對錯誤進行確認。例如:一次只修改一段程式區塊。

2.3 確定錯誤產生的原因
此步驟包括尋找類似的錯誤並查詢是否有類似的程式需要一併修正。

2.4 找出修正錯誤的解決辦法
此步驟可依不同程式語言所提供的除錯工具並找出修正錯誤的解決辦法。

2.5 修正錯誤,重新測試
最後依解決辦法進行修正錯誤並重新測試。

關於程式除錯,須注意以下的特性:

程式即便是正常執行,仍有可能隱藏錯誤

經過完整測試後的程式,亦有可能會有錯誤

語法錯誤(Syntactic errors)一般編譯器都會找出來這種錯誤

語義錯誤(Semantic errors)是編譯器所無法檢查出來的錯誤

良好的測試案例與清晰的程式碼註解可增近除錯的效率

典型除錯技術包括:
(1)單步執行(Single-stepping)
(2)插入中斷點(Breakpoint)
(3)新增並追蹤額外變數法
(4)在問題點附近加入Try/Catch等方式以利於鎖定錯誤範圍

3. 除錯實務應用

在除錯實務應用中,R語言提供以下除錯函數,以利於錯誤發生時,允許程式設計師採取某些行動,進而達到除錯目的。

3.1 traceback()
如果程式錯誤並已完全終止,此時立即使用 traceback 將顯示錯誤前的最近執行的語法。

參考圖2 traceback 除錯結果,圖中顯示 traceback 會採用由上至下的方式取出錯誤堆疊(Stack)的結果,因此先顯示h(b)第2行的錯誤訊息,其次為g(a),最後才是f(1)。


圖2 traceback除錯

3.2 debug()
traceback 只能指出錯誤的發生處,並不能幫助使用者找出程式的錯誤。debug 可以逐行執行並提供互動式的除錯功能。debug 提供函數作為參數輸入,因此對於使用者建立或內建函數除錯提供更有用的除錯資訊。完成除錯後可使用 undebug 來移除 debug 功能。debug 可以輸入下四種指令與R函數,例:ls()函數:

n 繼續執行下一行程式,按下[Enter]鍵亦可。

c 繼續執行後續所有程式並回傳結果。

Q 中斷程式。

where 顯示呼叫所有函數堆疊。

參考圖3 debug 除錯結果,考慮計算總平方差(Sum of Squared Differences,SSD)並建立SSD函數,僅接著使用n與ls函數()進行debug除錯。


圖3 debug除錯

3.3 browser()
在上述 debug() 函數中可以逐行除錯,如果希望在特定程式碼中進行除錯,此時可使用 browser() 函數,將程式暫時中斷並等待使用者輸入。

參考圖4 browser 除錯結果,考慮修正上個步驟計算總平方差並建立SSD函數。


圖4 browser除錯

3.4 try()
參考圖5 try 除錯結果,考慮log輸入不正確字元參數 RWEPA,其結果會顯示Error而中斷程。修正後加上 try 函數即可繼續執行後續程式並顯示log(3)之結果。try(…, silent=TRUE)函數,其結果會隱藏錯誤訊息。


圖5 try除錯

3.5 tryCatch()
參考圖6 tryCatch除錯,如果希望針對錯誤(Error)或警告(Warning)等不同情形,提供對應的解決方式,此時可考慮使用 tryCatch 函數。範例中分別加上 warning 與 error 的處理方式,因此程式不會中止,而可顯示不同結果。


圖6 tryCatch除錯

3.6 withCallingHandlers()
withCallingHandlers 與 tryCatch 功能類似。主要有兩大區別,分別參考圖7 withCallingHandlers除錯-回傳值與圖8 withCallingHandlers除錯-運作方式與以下說明:

tryCatch()處理程序的回傳值由tryCatch()定義,而 withCallingHandlers()的回傳值會被忽略,參考圖7。


圖7 withCallingHandlers除錯-回傳值

使用sys.calls()查閱對應的中間過程,withCallingHandlers 的運作方式相當於 traceback 用法,如下所示,它列出了導致當前函數的所有調用,參考圖8。


圖8 withCallingHandlers除錯-運作方式

4. shiny除錯

shiny套件是網頁應用程式,一般只有在shiny程式執行時,才會顯示程式是否正常執行。例:在"01_hello" 範例中,如果須測試 input 輸入控制項之結果,則可在bins之前先行輸入 # input <- list(bins=30) 前面加上#,以免正式執行時,永遠bins為30。總而言之,輸入控制可於input中宣告為list,以利事先了解其執行結果或加速shiny除錯,詳細結果參考圖9所示。

library(shiny)
runExample("01_hello")
output$distPlot <- renderPlot({ x <- faithful$waiting bins <- seq(min(x), max(x), length.out = input$bins + 1)


圖9 shiny除錯

5. 效能提升

一般考慮以下方式,可提升程式執行效能:

(1)採用矩陣運算

(2)使用圖形處理器(graphics processing unit,GPU)運算

(3)使用平行運算處理技術,主要包括資料平行處理和工作平行處理(data parallelism and task parallelism)。


2018年4月7日 星期六

R資料匯入與匯出

R資料匯入與匯出

# read.table
# read.csv
# read.fwf
檔首無BOM
# readxl 套件
RODBC 套件
# lapply
# do.call

本篇說明資料匯入與匯出。首先介紹ETL概念,其次介紹常用的資料檔案,包括文字檔案、Excel檔案、資料庫資料、JSON檔案。資料庫的匯入將以Microsoft SQL Server說明為主。最後以單一檔案較大者的「大型資料」匯入與檔案數目較多者的「大量資料」匯入等議題做為本篇的結束。


1. ETL簡介


隨著科技的進步,企業經常面對資料處理、轉換或整合等應用。「ETL (Extract-Transform-Load)擷取轉換載入」是資料分析中的基礎的應用,最早興起於1970年資料倉儲中資料庫的處理程序。ETL表示資料由資料來源端擷取 (Extract) 出來,經過轉換 (Transform),再載入 (Load)到目的端的資料傳輸整體過程。進行ETL程序時,常用串流方式方法避免資料讀取時記憶體耗盡,參考圖1所示。


圖1 ETL流程圖

擷取:從各種不同的資料來源中,將資料擷取出來。資料來源包括交易型資料庫,同質資料與異質資料來源,資料擷取具有以下特性:

  1. 可能有各式各樣的資料來源和不同的資料格式,在利用程式語言開發或使用現有工具時,必須將來源資料轉換成共同資料格式。
  2. 擷取出來的資料,比對其格式和結構是否符合所需,例如:是固定欄位長度內容的資料、還是用區隔符號定義的資料。
  3. 擷取出來的資料若不符合所需,則依照相對應的規則以決定該採取何種反應,如:另外紀錄錯誤問題並發出警告,但整個ETL流程仍繼續執行。
  4. ETL作業能擷取一個檔案或同時進行多個來源端的資料擷取。

轉換:對資料進行適當的轉換,如型態轉換、字串相連、彙總運算等,本階段會將資料儲存成適當的格式,以利事後查詢與分析。這個步驟在 ETL 中不一定需要執行。

資料轉換具有以下特性:

  1. 可針對Excel、HTTP Web Page、XML、PDF與 Binary data 資料格式等檔案格式進行資料轉換。
  2. 基於商業邏輯上的需求,必須依照應用程式資料的特性來分類、匯總、轉換資料型態;或是把經年累月所聚集的歷史資料來作合併、統計、分折及計算。
  3. 本階段的轉換元件與功能通常是最多元、最豐富的,往往也是決定ETL產品的重要考量之一。
  4. 資料轉換就是將所擷取出之資料,交付予資料轉換元件(例:log資料轉換元件),逐一並循序地依照所設計好的規則進行轉換。
  5. 載入:將資料載入目的端,目的端通常是為了報表產製及商業智慧分析而最佳化的資料倉儲。

2. 文字檔案

常用的文字檔案包括以逗號分隔值檔案(Comma-Separated Values File,簡稱CSV File),其檔案以純文字形式儲存數字和文字資料。CSV檔案亦稱為字元分隔值檔案(Character-Separated Values File),因為分隔字元也可以不是逗號,例:分號(;)、Tab符號(–>)、bar符號(|)與空白字元。CSV檔案具有以下特性:


  1. 採用純文字,使用某個字元集,例:ASCII、Unicode、UTF-8或GB2312(簡體中文環境)等儲存。
  2. 每一橫列為一筆記錄組成。
  3. 每一筆記錄以分隔符號區分欄位。
  4. 每一筆記錄都具有相同的欄位順序。
  5. 在Windows環境中使用 Microsft Office Excel 等軟體執行 檔案\另存新檔\存檔類型\ 選取「CSV(逗號分隔)()*.csv」 \ 按儲存 即可儲存為CSV檔案。
  6. 開啟CSV檔案時,最後一列為空白列,該空白列須保留不可刪除,否則匯入至R/Python會有問題。參考圖2,其中第12列為空白列。


圖2 production.csv範例

範例1:匯入production.csv檔案。

CSV檔案匯入與資料分析工作包括以下五大步驟:


步驟1 設定工作目錄:

一般資料的匯入與匯出可以先考量工作目錄的概念。R/Python軟體具有工作目錄(Working Directory)概念,即預設讀取資料的目錄。以下說明以Windows 10作業系統與R軟體[https://www.r-project.org/]操作為主。使用getwd函數以取得工作目錄,設定工作目錄為setwd函數。本範例考慮工作目錄為「C:/rdata」。

setwd("C:/rdata")
getwd()
## [1] "C:/rdata"

步驟2 準備資料檔案:


本步驟為準備好即將匯入至R的資料檔案,一般初步使用建議將資料轉換為CSV檔案較方便於後續資料匯入。下載production.csv並儲存至C:\rdata。

資料來源:production.csv

步驟3 匯入資料:

常用匯入資料為read.table函數,使用彈性較大,read.csv函數為限用CSV檔案。本例使用read.table函數以匯入CSV檔案。“production.csv”表示檔案名稱,header=TRUE表示第一列為資料欄名稱,sep=“,”表示資料以逗號區隔欄位,stringsAsFactors=FALSE表示不會將字串自動轉換為因子(Factor),而保持原字串資料型態。匯入至R之資料物件名稱為production,資料顯示為10筆,5個欄位。如果匯入資料產生亂碼情形,則可考慮以下三種解決方式:

  1. 使用記事本等軟體,將資料另存新檔且編碼設定為ANSI。
  2. 在read.table函數中加入 fileEncoding=“UTF-8”或適當編碼。
  3. 在read.table函數中加入 encoding=“UTF-8”或適當編碼。


production <- read.table("production.csv", header=TRUE, sep=",", stringsAsFactors=FALSE)
production
##    工號 生產日期 機台 生產量 目標量
## 1     1 2017/4/1    A     50     60
## 2     2 2017/4/1    A     60     60
## 3     2 2017/4/1    A     40     60
## 4     2 2017/4/2    B     70    100
## 5     3 2017/4/2    B    120    100
## 6     3 2017/4/3    B     80    100
## 7     4 2017/4/3    C     30     50
## 8     1 2017/4/4    C     35     50
## 9     4 2017/4/4    C     60     50
## 10    2 2017/4/4    C     80     50

步驟4 資料分析:

資料匯入完成後,首要步驟是分別使用str函數與summary函數進行資料結構理解與統計摘要分析。int表示整數(Integer),chr表示字串(String)或稱為字元(Chacter)。summary函數會輸出以下6個統計量:

  1. Min :最小值(Minimum)
  2. 1st Qu :25百分位數,符號 Q1
  3. Median :中位數,符號 Q2
  4. Mean :平均數
  5. 3rd Qu :75百分數位,符號 Q3
  6. Max :最大值(Maximum)

str(production)
## 'data.frame':    10 obs. of  5 variables:
##  $ 工號    : int  1 2 2 2 3 3 4 1 4 2
##  $ 生產日期: chr  "2017/4/1" "2017/4/1" "2017/4/1" "2017/4/2" ...
##  $ 機台    : chr  "A" "A" "A" "B" ...
##  $ 生產量  : int  50 60 40 70 120 80 30 35 60 80
##  $ 目標量  : int  60 60 60 100 100 100 50 50 50 50
summary(production)
##       工號       生產日期             機台               生產量     
##  Min.   :1.0   Length:10          Length:10          Min.   : 30.0  
##  1st Qu.:2.0   Class :character   Class :character   1st Qu.: 42.5  
##  Median :2.0   Mode  :character   Mode  :character   Median : 60.0  
##  Mean   :2.4                                         Mean   : 62.5  
##  3rd Qu.:3.0                                         3rd Qu.: 77.5  
##  Max.   :4.0                                         Max.   :120.0  
##      目標量   
##  Min.   : 50  
##  1st Qu.: 50  
##  Median : 60  
##  Mean   : 68  
##  3rd Qu.: 90  
##  Max.   :100
# 新增達成率欄位,計算方式為生產量/目標量
production$達成率 <- round((production$生產量/production$目標量)*100)
production
##    工號 生產日期 機台 生產量 目標量 達成率
## 1     1 2017/4/1    A     50     60     83
## 2     2 2017/4/1    A     60     60    100
## 3     2 2017/4/1    A     40     60     67
## 4     2 2017/4/2    B     70    100     70
## 5     3 2017/4/2    B    120    100    120
## 6     3 2017/4/3    B     80    100     80
## 7     4 2017/4/3    C     30     50     60
## 8     1 2017/4/4    C     35     50     70
## 9     4 2017/4/4    C     60     50    120
## 10    2 2017/4/4    C     80     50    160

# 繪製達成率統計圖
plot(production$達成率, xlab="人次", ylab="達成率(%)", main="2018年達成率統計圖", type="b", sub="製表:RWEPA, March 12, 2018")



步驟5 匯出分析結果:

最後步驟是將分析的結果,包括文字與圖檔等進行資料匯出,常用的文字資料匯出函數是write.table與R專用資料格式(RData)save函數。本例使用write.table函數 匯出成production.output.csv檔案,使用save函數匯出成production.output.RData。

write.table(production, file="production.output.csv", sep=",", row.names=TRUE)
save(production, file="production.output.RData")

如果文字檔案是採用固定寬定方式儲存,則匯入資料時可採用  read.fwf 函數匯入。例:固定寬度檔案名稱是 myfix.txt,資料寬度分別為1, 2, 3個空白字元, 4個字元,則匯入方法如下,其中 -3 表示跳過3行不讀取:

read.fwf("myfix.txt", widths = c(1, 2, -3, 4))

3. Excel檔案

Excel檔案是常用辦公室資料檔案格式,除了以Microsoft Office Excel軟體進行操作,另外可使用readxl套件匯入Excel檔案並進行資料操作處理。

範例2:匯入 production.xlsx 檔案。

首先將範例1的 production.csv 另儲存成 production.xlsx。使用 excel_sheets函數理解工作表個數,使用 read_excel讀取工作表,其中mydf1,mydf2,mydf3結果皆相同。

library(readxl)
# 顯示工作表名稱
datasets <- "production.xlsx"
excel_sheets(datasets)
## [1] "production"
# 讀取Excel檔案
mydf1 <- read_excel(datasets) # 預設讀取第1個工作表
mydf2 <- read_excel(datasets, 1) # 指定第1個工作表
mydf3 <- read_excel(datasets, "production") # 指定工作表名稱

mydf1
## # A tibble: 10 x 5
##     工號 生產日期            機台  生產量 目標量
##    <dbl> <dttm>              <chr>  <dbl>  <dbl>
##  1  1.00 2017-04-01 00:00:00 A       50.0   60.0
##  2  2.00 2017-04-01 00:00:00 A       60.0   60.0
##  3  2.00 2017-04-01 00:00:00 A       40.0   60.0
##  4  2.00 2017-04-02 00:00:00 B       70.0  100  
##  5  3.00 2017-04-02 00:00:00 B      120    100  
##  6  3.00 2017-04-03 00:00:00 B       80.0  100  
##  7  4.00 2017-04-03 00:00:00 C       30.0   50.0
##  8  1.00 2017-04-04 00:00:00 C       35.0   50.0
##  9  4.00 2017-04-04 00:00:00 C       60.0   50.0
## 10  2.00 2017-04-04 00:00:00 C       80.0   50.0

mydf2
## # A tibble: 10 x 5
##     工號 生產日期            機台  生產量 目標量
##    <dbl> <dttm>              <chr>  <dbl>  <dbl>
##  1  1.00 2017-04-01 00:00:00 A       50.0   60.0
##  2  2.00 2017-04-01 00:00:00 A       60.0   60.0
##  3  2.00 2017-04-01 00:00:00 A       40.0   60.0
##  4  2.00 2017-04-02 00:00:00 B       70.0  100  
##  5  3.00 2017-04-02 00:00:00 B      120    100  
##  6  3.00 2017-04-03 00:00:00 B       80.0  100  
##  7  4.00 2017-04-03 00:00:00 C       30.0   50.0
##  8  1.00 2017-04-04 00:00:00 C       35.0   50.0
##  9  4.00 2017-04-04 00:00:00 C       60.0   50.0
## 10  2.00 2017-04-04 00:00:00 C       80.0   50.0

mydf3
## # A tibble: 10 x 5
##     工號 生產日期            機台  生產量 目標量
##    <dbl> <dttm>              <chr>  <dbl>  <dbl>
##  1  1.00 2017-04-01 00:00:00 A       50.0   60.0
##  2  2.00 2017-04-01 00:00:00 A       60.0   60.0
##  3  2.00 2017-04-01 00:00:00 A       40.0   60.0
##  4  2.00 2017-04-02 00:00:00 B       70.0  100  
##  5  3.00 2017-04-02 00:00:00 B      120    100  
##  6  3.00 2017-04-03 00:00:00 B       80.0  100  
##  7  4.00 2017-04-03 00:00:00 C       30.0   50.0
##  8  1.00 2017-04-04 00:00:00 C       35.0   50.0
##  9  4.00 2017-04-04 00:00:00 C       60.0   50.0
## 10  2.00 2017-04-04 00:00:00 C       80.0   50.0

範例3:參考圖3,使用Excel開啟CSV檔案會有亂碼情形。


圖3 CSV檔案亂碼

改善方式之一是考慮使用文字編輯軟體,修改編碼方式,本例使用免費軟體Notepad++,將編碼由原先的「編譯成UTF-8碼(檔首無BOM)」修改為「編譯成 UTF-8 碼」,再儲存檔案後使用Excel開啟即沒有亂碼,詳細參考圖4之設定。


圖4 CSV檔案亂碼-UTF-8


4. 資料庫資料


關於微軟(Microsoft)大量結構性資料匯入與匯出,Microsoft SQL Server提供以下工具:


  1. bcp公用程式 (bulk copy program): 提供大量資料匯入與匯出功能,可以由使用者指定格式,在 Microsoft SQL Server 執行個體與資料檔案之間大量複製資料。
  2. BULK INSERT 陳述式:可將資料直接從資料檔案匯入至資料庫資料表或非資料分割的檢視,不提供匯出資料功能。
  3. BULK INSERT 陳述式與 INSERT…SELECT * FROM OPENROWSET(BULK…) 陳述式 :將大量資料檔案匯入到 SQL Server 資料表中,不提供匯出資料功能。
  4. SQL Server Data Tools (SSDT) 來執行 SQL Server 匯入和匯出精靈。

資料來源:https://docs.microsoft.com/zh-tw/sql/relational-databases/import-export/bulk-import-and-export-of-data-sql-server

R可採用 RODBC 套件與Microsoft SQL Server資料庫連結,其中 sqlQuery 函數可執行資料匯入至R/R物件寫入SQL資料庫,部分執行畫面參考圖5,詳細參考 RODBC 與 SQL Server 資料匯入與寫入

圖5 RODBC-寫入


5. JSON檔案


JSON(JavaScript Object Notation)是一種由Douglas Crockford 構想和設計、輕量級的資料交換語言,該語言以易於讓人閱讀的文字為基礎,用來傳輸由屬性值或者序列性的值組成的資料物件。儘管JSON是Javascript的一個子集,但JSON是獨立於語言的文字格式,並且採用了類似於C語言家族的一些習慣,詳細參考官方網站[http://www.json.org/]

資料來源:https://en.wikipedia.org/wiki/JSON

JSON資料物件包括:

  1. 物件 object : {name:value}
  2. 陣列 array : [x1, x2, …]

JSON資料型態包括:

  1. 空值(null)
  2. 邏輯值(true, false)暨布林值。
  3. 數值(number),沒有區分整數與具有小數點數。
  4. 字串(string)。

RJSONIO 套件提供以下二大函數,詳細參考函數線上說明:


  1. toJSON() : 轉換 R 物件為 JSON 字串。
  2. fromJSON() : 轉換 JSON物件為 R 物件, 資料來源包括 URL, File, R物件。

JSON資料參考圖1.4.6 JSON-錄影節目影片範例。


圖6 JSON-錄影節目影片範例

資料來源:http://vida.moc.gov.tw/VIDA411.ASP?ISSUEYM=10306


6. 大型資料


大型資料指的是單一檔案較大,使用傳統read.table或read.csv函數可能匯入時間教長,此時可使用data.table套件的fread函數以提升匯入效能,詳細參考以下圖7 大型資料範例。



圖7 大型資料範例

上述大型資料亦可使用 bigmemory套件匯入資料,參考圖8 大型資料-bigmemory範例。



圖8 大型資料-bigmemory範例


7. 大量資料


大量資料指的是檔案較多時,使用傳統 read.table或 read.csv函數逐一匯入較不方便,此時可使用 lapply函數,詳細參考以下大量資料範例,考慮將三個檔案,每個檔案是10列5行,合併為單一資料物件30列5行。

lapply 函數主要包括2個參數 lapply(資料物件, 函數),其回傳結果是串列(list):

  1. 第一個參數是須要處理的資料物件,一般是向量資料,本例 files 表示三個檔案路徑。
  2. 第二個參數是函數,本例是 read.table,後續 header=TRUE, sep="," 是配合 raed.table使用。

do.call 函數是將三個串列合併為一個資料框(data.frame)。

# 大量資料範例
working_path <- "C:/rdata"
setwd(working_path)
getwd()
## [1] "C:/rdata"
sample1 <- iris[sample(1:nrow(iris),10),]
sample2 <- iris[sample(1:nrow(iris),10),]
sample3 <- iris[sample(1:nrow(iris),10),]

write.table(sample1, file="sample1.csv", sep=",", row.names=FALSE)

write.table(sample2, file="sample2.csv", sep=",", row.names=FALSE)
write.table(sample3, file="sample3.csv", sep=",", row.names=FALSE)

files <- dir(getwd(), pattern="sample.*.csv", recursive=TRUE, full.names=TRUE)

files
## [1] "C:/rdata/sample1.csv" "C:/rdata/sample2.csv" "C:/rdata/sample3.csv"

tables <- lapply(files, read.table, header=TRUE, sep=",") # list

sample.all <- do.call(rbind, tables) # data.frame

str(sample.all)
## 'data.frame':    30 obs. of  5 variables:
##  $ Sepal.Length: num  5.4 4.7 5.7 6.3 6.6 7 5 4.4 5.4 6.3 ...
##  $ Sepal.Width : num  3.9 3.2 2.8 2.5 3 3.2 3.6 3 3 2.5 ...
##  $ Petal.Length: num  1.7 1.3 4.1 5 4.4 4.7 1.4 1.3 4.5 4.9 ...
##  $ Petal.Width : num  0.4 0.2 1.3 1.9 1.4 1.4 0.2 0.2 1.5 1.5 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 2 3 2 2 1 1 2 2 ...
# end