Loading...
Data ScienceR

Data ไสย์ Tutorial เดอะซีรี่ส์ #1 – มังกรสองตัว อยู่ถ้ำเดียวกันได้มั้ยฮึ (1/2)

Source: Wikimedia Commons

“เสือสองตัวอยู่ถ้ำเดียวกันไม่ได้” เป็นสุภาษิตไทย แต่วันนี้ขอพาขึ้นเหนือไปไกลหน่อย อย่างน้อยให้เลยชายแดนเวียดนามไปทางเหนือ เพราะเราจะไม่ได้พูดเรื่องเสือ แต่เป็นเรื่องของมังกรล้วนๆ

ช่วงปลายปีที่แล้วลามมาถึงต้นปีนี้ บังเอิญ (น่าจะใช้คำนี้ได้) ไปเป็น expat ไทยในในแดนมังกรอยู่หลายอาทิตย์ ระหว่างนั้นก็ไปเจองาน data visualization พื้นๆ ที่น่าจะเก็บไว้เป็นตัวอย่าง หรือเป็น snippet ในงานอื่นได้บ้าง เลยเป็นที่มาของ article แรกในซีรี่ส์นี้ ขอรับประกันว่าง่ายและทำตามได้แน่นอน เพราะเรื่องยากๆ เราก็ทำไม่เป็น

โจทย์ที่ตั้งขึ้นมาตอนแรก:

“ถ้ามี dataset เป็น interger จำนวน 1 column ที่ represent จำนวนอะไรซักอย่าง แล้วมีอีก column  เป็น identity ทำให้สามารถ group ตามเขตการปกครองท้องถิ่นของประเทศจีนได้ โดยที่ตัวมันเองที่ดูเหมือนเป็น time series (แปลว่ามีหลายวัน และวันละหลาย row) เราจะ visualize มันออกมาได้ยังไงบ้าง” เงามังกรเริ่มโผล่มาละครับท่านผู้ชม

* ตั้งเป็นโจทย์ไว้แบบไม่มีทิศทาง เพราะตอนนั้นยังไม่ได้ data จริงๆ มา ตัว metadata ก็ไม่มี เลยต้อง mockup ทุกอย่างขึ้นมาเพื่อลองดูความเป็นไปได้ที่จะทำงานต่อ เสกข้อมูลขึ้นจากอากาศแท้ๆ เลยทีเดียว

ตัวอย่าง dataset ที่จุดธุปเรียกมา
ตัวอย่าง dataset ที่จุดธุปเรียกมา

โจทย์ตั้งมามีธงขนาดนี้ จะทำ ANN ก็ต้องลำบากมาจุดธูปสร้าง mock data จากความว่างเปล่าให้ data มีเนื้อหนังมากพอจะหา correlation เดี๋ยวจะไปกันใหญ่ เอาง่ายๆ ไปก่อนตามสไตล์ KISS

plot map สิวะ” เสียงจาก partition ข้างๆ
เออ ตามนั้น” ตอบไปเบาๆ ลืมไปสนิทว่าทั้งชั้นไม่มีคนไทย…

มังกรตัวที่หนึ่ง: มังกรอาฮ่า

อะไรเอ่ย ฟรี ไลบรารี่เยอะ เรียน Data Science ที่ไหนก็ชอบสอนให้ใช้
มันต้องมีคนคิดถึง R บ้างล่ะวะ คู่ทุกคู่ยากมนุษย์ data มานาน
นึกอะไรไม่ออกก็หยิบ sample เข้ามา summary head crosstab ดูใน R ทุกที
เริ่มเลย

* ขอโกงหน่อย ขี้เกียจ read csv มา clean เลย mock dataset ใหม่ขึ้นมาดื้อๆ ละกัน ตั้งโจทย์เองแก้โจทย์เองก็งี้แหละ ขนาดจัดเลือกตั้งยังหา สว. เข้ามาเองได้เลย

อธิบายโค้ดที่ละส่วน ค่อยๆ ทำไล่ไป

Import library ประมาณนี้ อันไหนไม่มีก็ install.packages(‘ชื่อ library’) ไปตามปกติ

library(maps)
library(mapdata)
library(rgdal)
library(plyr)
library(classInt)
library(RColorBrewer)
library(ggplot2)
library(maptools)

จะเห็นว่า library ตัวนึงชื่อ mapdata ซึ่งเป็น standard dataset ทำให้เราสามารถใช้คำสั่งข้างล่าง plot แผนที่ประเทศจีนออกมาได้เลย

map("china")
map("china", col = "gray40", ylim = c(18,54))

อ้าว จบแล้วดิเนี่ย เอา data มาทำ range เลือกสีก็เสร็จ จะเขียนทำไมยืดยาว
เดี๋ยวก่อนครับ ดูตรงนี้นะ

ฉงชิ่งที่หายไปจาก R mapdata
ฉงชิ่งที่หายไปจาก R mapdata

ตรงวงกลมสีแดงนั้นเป็นทิศตะวันออกของเมืองเฉิงตู มณฑลเสฉวน ที่ปัจจุบันแยกมาเป็นเทศบาลนครของตัวเองชื่อว่าเมืองฉงชิ่ง ขึ้นตรงกับรัฐบาลกลาง มีฐานะเท่ากับปักกิ่ง เซี่ยงไฮ้และเทียนจิน แต่ dataset ใน mapdata ของ R ยังไม่อัพเดทจ้า จะตัดทิ้งหรือทำเป็นไม่สนใจก็ไม้ได้ เพราะฉงชิ่งดันเป็นเขตเมืองขนาดใหญ่อย่างที่บอก งานเริ่มงอกแล้ว

อย่าเพิ่งเปลี่ยนอาชีพเลิกสนใจ data ไปทำอย่างอื่น ผมหา solution ให้แล้ว
หลังจากงมหาอยู่หลายชั่วโมง ก็เจอ shape file แผนที่ประเทศจีนแบบอัพเดทล่าสุด (หลัง 2010) จาก StatPlanet
วิธีใช้ก็คือ read เข้ามาแบบนี้เลย

china_a <- readOGR('StatPlanet_China/map/map.shp')

* อย่าลืม  setwd(”) ให้เป็น current path ของไฟล์ R ด้วยนะ

ลอง examine data ดู จะเห็นว่ามีชื่อเมือง เขตการปกครอง กับ shape data ที่เข้าใจยากหน่อย ก็ข้ามไปได้
แค่ลองเช็ค length ดูว่ามันมี 32 เขตการปกครองก็ถือว่าใช้ได้ละ ของเดิมมันมี 31 เขตเพราะไม่ได้แยกฉงชิ่งออกมา

head(china_a@data)
length(china_a)

หลังจากนั้นก็ trim data นิดหน่อยเพื่อตัดส่วนที่ไม่ใช่แผ่นดินใหญ่ออก ซึ่งกรณีนี้ตัดได้แล้ว เพราะเป็นพวกเมืองเล็กๆ และ dataset ที่เราจะ visualize ไม่ค่อยมีข้อมูลจากเมืองระดับนี้

china_a <- china_a[,-(1:5)]
china_a <- china_a[,-c(9, 10)]

ลอง plot ดูใหม่ จะเห็นฉงชิ่งโผล่มา รอดไปเรื่องนึง

plot(china_a)
ฉกชิ่งที่กลับมาแล้ว จาก Shape File
ฉงชิ่งที่กลับมาแล้ว จาก Shape File

ช่วงนี้เป็นการ mockup data ลงใน map อย่างที่บอกว่าไม่อยาก load sample data ที่เตรียมไว้เพราะแค่หา shape file ก็ใช้เวลาเยอะเกินไปแล้ว
อธิบายขั้นตอนเร็วๆ คือ random เลขมาตามจำนวนพื้นที่ (เมือง) แล้วก็แปะลงไปในแต่ละส่วนของ map เพราะเราจะ  plot มันออกมาเป็นสีๆ

set.seed(100)
myvar <- rnorm(1:length(china_a))
 
# add data to table
china.geodata <- data.frame(id=rownames(china_a@data), mapvariable=myvar)
head(china.geodata)
china.dataframe <- fortify(china_a)
 
# join map coordinates with data
china.dat <- join(china.geodata, china.dataframe, by="id")
head(china.dat)

ถึงขึ้นตอนการ plot แล้ว ลองทำไปสองแบบคือ basic plot ใช้ brewer 5 สี แบบตัดเลือก interval อัตโนมัติ (ค่ำแล้วอยากรีบกลับไป งานเลยหยาบๆ หน่อย)

# basic plot
nclassint <- 5
cat <- classIntervals(myvar, nclassint,style = "jenks")
colpal <- brewer.pal(nclassint,"RdBu")
color <- findColours(cat,rev(colpal)) 
bins <- cat$brks
lb <- length(bins)
 
plot(china_a, col=color,border=T)

ได้ออกมาแบบนี้

Basic Plot แบบรีบๆ
Basic Plot แบบรีบๆ

กับอีกแบบ ggplot2 ยอดนิยม ใช้ range สีตามที่ tutorial ส่วนใหญ่เค้าชอบกัน

# GG plot
p <- ggplot(data=china.dat, aes(x=long, y=lat, group=group))
p <- p + geom_polygon(aes(fill=mapvariable)) +
geom_path(color="white",size=0.1) +
coord_equal() +
scale_fill_gradient(low = "#ffffcc", high = "#ff4444") +
labs(title="",fill="")
p

ได้ออกมาแบบนี้

แค่ใช้ GGPlot2 ก็ดูแพงขึ้นมาทันที
แค่ใช้ GGPlot2 ก็ดูแพงขึ้นมาทันที

สรุปว่าได้ map ออกมาตามโจทย์ แต่ก็เหมือนยังไม่ค่อยสุด
ขี้เกียจทำ leจง legend อะไรทั้งสิ้น หิว จะรีบไปหาก๋วยเตี๋ยวฉงชิ่งกิน

หน้าตางานใน R Studio
หน้าตางานใน R Studio

ตอนต่อไปรอพบกับมังกรตัวที่สอง บอกเลยว่าไม่ทำดา (โม้เก่ง)