สวัสดีครับ

บทความนี้ผมเขียนขึ้นมาเพื่อให้ท่านผู้อ่านได้รู้จักกับประโยชน์ของภาษา R ( R Language ) นะครับ โดยเฉพาะผู้ใช้ Excel คำนวนอยู่เป็นหลัก และกำลังมองหาเครื่องมือคำนวณที่มันแจ่มๆอยู่ /สนใจจะใช้ / กำลังจะเริ่มต้นใช้ / กลัวการเขียนโค้ด

จะบอกว่าผมเองก็พึ่งเริ่มต้นกับ R เหมือนกันครับ ผมทำงานสายธุรกิจ เรียนภาษานี้มาได้ครึ่งปี (ตอนนี้หยุดก่อน) โดยที่ไม่มีพื้นฐาน Coding / Programming มาก่อนครับ ดังนั้นสิ่งที่กำลังจะโชว์ให้ดู มันไม่ได้ซับซ้อนยากเย็นอะไรครับ สำหรับผู้ที่ใช้ R เป็นอยู่แล้ว ก็เป็นเรื่องพื้นๆเลยครับ

ก่อนเข้าเรื่อง อยากเล่าว่าเมื่อก่อนผมใช้ Excel ทำงานแต่ผม (จำใจ) เริ่มใช้ R เพราะเจอปัญหาหลักๆดังนี้บน Excel ครับ

1 จุข้อมูลได้แค่ ล้านกว่า row แต่ข้อมูลที่ผมจะใช้มันดันเกิน
2 พอไฟล์ใหญ่ๆ แฮงค์แล้วแฮงค์อีก
3 Calculation บางอย่างทำไม่ได้ โดยเฉพาะ model ที่เริ่มซับซ้อน
4 งานซ้ำๆ ขี้เกียจมาเริ่มใหม่ เขียน template หรือ macro แล้วก็ยังไม่เวิก (แล้วผมก็คิดอยู่นานว่าจะเพิ่มประสิทธิภาพด้วยการเรียน VBA หรืออย่างอื่นดี)

ปัญหาหนึ่งที่ทำให้ผมต้องใช้ภาษา R เป็นเพราะข้อนี้เลยครับ

5 ผมไม่สามารถใช้ Excel พล้อตกราฟที่ต้องการได้

ดังนั้นบทความเรื่อง “เหตุใดเราใช้ ภาษา R แทน Excel” ในตอน 1 ผมขอยกตัวอย่างของที่จับต้องง่ายๆ เช่นกราฟก่อนเลยนะครับ เพราะมันพล้อตได้เทพจริงๆครับ

Code ตัวอย่างผมจะแปะไว้ท้ายสุดนะครับ (แบบคร่าวๆครับ)

ตัวอย่างที่ 1

มีข้อมูลตัวอย่างร้านค้าแห่งหนึ่งเป็นเวลา 1 ปี ให้สรุปและเขียนกราฟให้น้อยที่สุด ว่า จำนวนบิลต่อชั่วโมง ในช่วงเช้าและช่วงบ่าย แบ่งตามวันแบบ weekday (อาทิตย์ – เสาร์) เป็นอย่างไร?

หมายเหตุ : ข้อมูลนี้ simulate เอานะครับ ไม่ใช่ข้อมูลจริง

หน้าตาข้อมูลประมาณนี้ครับ ทั้งหมด 4000 กว่า row

GornNutagorn_data_box

สนใจดูแค่คอลัมน์ดังนี้พอครับ
Day(Week) ค่า 1 คือวันอาทิตย์ ….ไปถึง ….. 7 คือวันเสาร์
Hour ค่า 1 คือช่วงเช้า (ก่อน 12.00น.) / ค่า 2 คือช่วงบ่าย (หลัง 12.00น.)
BillCount คือจำนวนบิลที่นับได้ใน 1 ชั่วโมง

**ในช่อง Hour
เลข 1 อาจเป็นช่วงเวลาใดก็ได้ใน 9.00-10.00 / 10.00 – 11.00 / 11.00 – 12.00
เลข 2 อาจเป็นช่วงเวลาใดก็ได้ใน 12.00-13.00 / 13.00 – 14.00 /……/ 19.00 – 20.00
ดังนั้น ข้อมูลช่วงบ่ายจะเยอะกว่าช่วงเช้า คือ จำนวน observation เยอะกว่าครับ

ถ้าให้ผมสรุปข้อมูลนี้โดย Excel ผมจะ

1 เอามา pivot โดยกำหนดให้
row = Day(Week)
column = Hour
value = ค่า mean ของ BillCount

2 พล้อตกราฟค่า mean จะได้รูปตามนี้

GornNutagorn_data_Excel_chart
กราฟ 1 : [Excel] ค่าเฉลี่ยจำนวนบิลต่อชั่วโมง ใน 7 วัน แบ่ง 2 ช่วง

ผลคือ ค่าเฉลี่ยบ่ายมากกว่าช่วงเช้าในทุกๆวัน

แต่ถ้ารู้สีกว่า รู้แค่นี้ไม่พอ อยากรู้ว่าข้อมูลกระจายตัวยังไง
ตัวผมเองไม่ค่อยชินกับเลข stat เท่าไหร่ ด้วยความขี้เกียจ จึงอยากจะเห็นทุกอย่างออกมาเป็นภาพ

คราวนี้ผมจะใช้ R พล้อตกราฟออกมา 2 แบบนี้ครับ

GornNutagorn_multi_boxplot
กราฟ 2 : [R] BOX-AND-WHISKER chart แท่งซ้ายไปขวา เรียง 7 วัน – รูปบนเช้า / รูปล่างบ่าย

GornNutagorn_multi_histogram
กราฟ 3 : [R] Histogram ฝั่งซ้ายเช้า / ฝั่งขวาบ่าย – เรียงลงมา 7 วัน
ทั้ง 2 รูปนี้ เขียนโค้ดไม่กี่บรรทัดครับ (โชว์ให้ดูตอนท้ายสุด)

ความเจ๋งของ R มันคือ

1 มันพล้อต BOX-AND-WHISKER chart กับ histogram ได้เลย (BOX-AND-WHISKER น่าจะพึ่งเริ่มมีใน excel 2016)
*BOX-AND-WHISKER คือ แสดงการกระจายข้อมูลโดยบอก quartile 1,2,3 และ outlier นะครับ

2 มันพล้อตได้ทีละหลายๆ chart ได้ในครั้งเดียวเลย ขึ้นอยู่กับว่า เราจะใส่อะไรลงไปใน factor เช่นอันนี้ factor ผมคือ ช่วงเช้าและบ่าย / วัน 7 วัน

การปรับแต่งชาร์ต อาจใช้เวลาสักหน่อย แต่ถ้าเชี่ยวแล้ว ก็ไม่ได้ยากอะไรนะครับ เขียนครั้งเดียว สามารถเก็บไว้ใช้ต่อได้เรื่อยๆด้วยครับ

ตัวอย่างที่ 2

ดูรูปแบบความสัมพันธ์ของค่าเงิน USD กับราคาทองในรูปเงิน USD (เทียบ EUR) ใช้ข้อมูลรายเดือนตั้งแต่ปี 1999 – 2017

ข้อมูลหน้าตาแบบนี้นะครับ

GornNutagorn_Excel_Data2

GornNutagorn_Excel_Chart
กราฟ 4 : [Excel] Scatter Plot ราคาทองและค่าเงิน พร้อม Linear Trend Line
GornNutagorn_LOESS
กราฟ 5 : [R] Scatter Plot ราคาทองและค่าเงิน USD พร้อม LOESS Smoother
GornNutagorn_LOESS2
กราฟ 6 : [R] Scatter Plot ราคาทองและค่าเงิน USD พร้อม LOESS Smoother แบ่ง 3 ช่วงเวลาคั่นที่ 1999 / 2005 / 2011/ 2017

ความเจ๋งของ R มันคือ

1. มันมี Trend Line หลายแบบ คือในกรณีที่ไม่รู้ว่า ข้อมูลกระจายตัวแบบไหน การใส่ Trend Line แบบเส้นตรงอาจไม่ใช่ตัวเลือกที่ดีที่สุด มันอาจทำให้ค่า Correlation และ R Square เพี้ยนตามไปด้วย
ดังนั้นผมจึงใส่ LOESS Smoother เพราะมันจะทำให้เห็นภาพความสัมพันธ์ได้เลยโดยเฉพาะในกรณีที่ข้อมูลจุดมันเยอะมากๆ
อีกอย่างคือถ้ามี 2 กลุ่มข้อมูลพล้อตซ้อนกันอยู่ในกราฟเดียวกัน มันสามารถ plot trend line 2 เส้น ในกราฟเดียวได้เลย
*LOESS ที่ว่าคือ LOWESS (Locally Weighted Scatterplot Smoothing) Line คือเส้นที่ใช้แสดงแนวโน้มความสัมพันธ์ ของปัจจัย 2 ตัว โดยไม่สนว่าข้อมูลจะกระจายตัวแบบไหน

2 ชอบที่มันพล้อตได้ทีละหลายๆกราฟอีกแหละครับ เมื่อผมสามารถแบ่งตามช่วงเวลาได้ ก็จะเห็นความสัมพันธ์หลายช่วง โดยที่ไม่ต้องมานั่งเปลี่ยนข้อมูลครับ

 

ตัวอย่างที่ 3

ข้อมูลราคาทองและดัชนีหุ้นรายเดือน ช่วง 2007-2010 โดยแต่ละเส้นคือ

Gold_USD (ราคาทองในรูปค่าเงิน USD)
SP500 (ดัชนี S&P500 – =ชี้หุ้นอเมริกา; 500 บริษัทใหญ่ ในตลาด NYSE และ NASDAQ)
NIKKEI (ดัชนี NIKKEI225 – ชี้หุ้นญี่ปุ่น; บริษัทชั้นนำ 225 แห่งใน Tokyo Stock Exchange)
STOXX50E (ดัชนี Euro Stoxx 50 – ชี้หุ้นยุโรป; บริษัทชั้นนำ 50 แห่งในยูโรโซน)

ลิงค์นี้คือหน้าที่ผมเอาไปใช้จริงนะครับ
https://www.facebook.com/GornNutagorn/photos/a.1146058602170328.1073741832.822344891208369/1146059858836869/?type=3&theater

GornNutagorn_Multi_Line_Chart
กราฟ 7 : [R] ข้อมูลราคาทองและดัชนีหุ้นรายเดือน ช่วง 2007-2010
ถ้าเป็น Excel ผมจะสามารถพล้อตครั้งเดียวได้ก็ต่อเมื่อ

1 มีแค่ 2 ดัชนีเท่านั้น และแบ่งเป็น Primary / Secondary Axis
2 ทำเป็น Chain Index (ดัชนีลูกโซ่)

ความเจ๋งของ R มันคือ ผมทำได้เลย โดยไม่ต้องแบ่ง และช่วงเวลาตรงกันแน่นอน
อันนี้แค่ตัวอย่างเล็กน้อยๆของ R นะครับ
รูปแบบกราฟของ R โดยใช้ ggplot2 ลองเข้าไปดูได้ที่นี่นะครับ

General Ggplot2 Tips

ถ้าผู้อ่านไม่เคยเรียนแต่สนใจที่จะเรียนภาษา R สำหรับคนไม่เคยเขียนโค้ดอย่างผมก็รู้สึกว่ามันยากสักหน่อย แต่ก็พอไหวอยู่นะครับ พอใช้งานมันได้แล้วจะรู้สึกว่ามันคุ้มมากๆเลยนะครับ

บทความนี้ค่อนข้างยาวแล้วครับ

ผมยังใหม่กับ R อยู่ ดังนั้น ถูกผิดอย่างไร ติชมได้เลยนะครับ และต้องขออภัยไว้ ณ ที่นี้หากข้อมูลผิดพลาดครับ บทความนี้ อย่างหนึ่งเขียนขึ้นเพื่ออยากเชิญชวนให้คนมาใช้ R ครับ มันทั้งฟรีและมันโหดมากเลยครับ

ขอบคุณที่อ่านมาถึงตรงนี้
เจอกันบทความหน้าครับ
(บทความนี้ เขียนเมื่อ 2017-03-27)

Created by : GornNutagorn

 

ช่องทางอื่นๆของ GornNutagorn

Facebook : https://www.facebook.com/GornNutagorn/

Youtube : www.youtube.com/c/GornNutagornChannel

 

Sponsored by :

#####################################

grocerlock_โกรเซอล็อค

 

สนับสนุนโดย : www.grocerlock.com (คลิกเพื่อเข้าเว็บ)

ซุปเปอร์มาร์เก็ตออนไลน์ ขายสินค้าอุปโภคบริโภคทั่วไป

ขายปลีก-ส่ง / ต่อรองได้ / ส่งทั่วประเทศ

FB อินบ้อกได้ที่ : https://www.facebook.com/grocerlock (คลิกเพื่อส่งข้อความทางอินบ็อกซ์)

ซื้อผ่านไลน์ได้ที่ Line ID : @grocerlock (คลิกเพื่อเพิ่มเพื่อน)

#####################################

 

##### ตัวอย่างโค้ด – ผมยังใช้ R Markdown ไม่เป็น ขอใส่มันโต้งๆเลยนะครับ #####

#####ผมเขียนค่อนข้างเวิ่นเว้อนะครับ จริงๆควรจะสั้นกว่านี้มาก เพราะไปดัดแปลงมาจากของที่เคยทำไว้แล้ว  ใส่ให้ดูเป็นตัวอย่างเท่านั้นครับ#####

library(xlsx)
library(ggplot2)
library(data.table)

## For Example 1 : Chart 2-3##

data1 <- fread("./data_transform2.csv",header = T)
data2 <- data1
colnames(data2)[4] <- "DM"
colnames(data2)[5] <- "DW"
data2$DM <- as.factor(data2$DM)
data2$DW <- as.factor(data2$DW)
data2$Hour <- as.factor(data2$Hour)
qplot(BillCount, data = data2, facets = DW~Hour, binwidth = 2)
qplot(DW,BillCount, data = data2,geom="boxplot",facets=Hour~.)
png(filename="multi_histogram.png",width=960,height=540)
qplot(BillCount, data = data2, facets = DW~Hour, binwidth = 2)
dev.off()
png(filename="multi_boxplot.png",width=960,height=540)
qplot(DW,BillCount, data = data2,geom="boxplot",facets=Hour~.)
dev.off()

## End ##

## For Example 2  : Chart 6 ##

library(xlsx)
library(ggplot2)
data_er1 <- read.xlsx("./data_er_trans.xlsx",header = T,sheetIndex = 1,colClasses = "numeric")
data_er2 <- data_er1
data_er2$TimeRange <- as.factor(data_er2$TimeRange)
erplot_trans1 <- (ggplot(data_er2, aes(x=EUR.USD, y=Gold_USD)) +
                geom_point() +
                geom_smooth(method="loess") +
                theme(axis.text.x=element_text(size=14),
                      axis.text.y=element_text(size=14),
                      axis.title.x=element_text(size=18),
                      axis.title.y=element_text(size=18))+
                facet_grid(.~TimeRange))
png(filename = "./erplot_trans1.png", width = 960,
    height = 540, units = 'px', res = 100)
erplot_trans1
dev.off()
## End ##

LEAVE A REPLY

Please enter your comment!
Please enter your name here