หากคุณกำลังเจอข้อมูลเน่าเฟะ อย่าเพิ่งสิ้นหวัง…
ทำอย่างไรเมื่อเจอข้อมูลที่อยู่ในรูปแบบที่แย่และไม่ ok เอาซะเลย และดันมีความจำเป็นต้องแก้ด้วย Power Query ซะด้วยสิ
ในบทความนี้เราจะมาเผชิญความเน่าเฟะไปด้วยกันครับ
เตือนไว้ก่อนว่าบทความนี้ยาวหน่อยและมีหลายขั้นตอน ซึ่งเป็นเรื่องปกติที่การกำจัดข้อมูลที่เน่าเฟะนั้นต้องใช้เวลา ดังนั้นอย่าเพิ่งท้อถอยนะครับ รับรองว่าจะได้ความรู้ดีๆ กลับไปแน่นอน
สารบัญ
ข้อมูลเน่าเฟะที่ได้มา
สมมติว่าเราได้ข้อมูลหุ้นในตลาด SET100 ทุกตัวหน้าตาแบบนี้มา ซึ่งผมใช้ Python ดึงมารวมกันแบบไม่ได้ Clean ดีๆ ตั้งแต่แรก (จะได้มาฝึกทำใน Power Query ไง 555)
ซึ่งดาวน์โหลดไฟล์ได้ที่นี่ (Google Drive / GitHub)
ความยาก1 มี Topic แทรกอยู่ระหว่างบรรทัดอยู่เป็นระยะๆ เช่น ทรัพย์สินรวม หนี้สินรวม
ความยาก2 จำนวนตัวเลขต่อ 1 Topic มี 4 ตัวบ้าง 5 ตัวบ้าง ไม่แน่นอน
ซึ่งความเป็นจริงคือข้อมูลย้อนหลังจนถึงปีปัจจุบัน Y-4, Y-3, Y-2, Y-1, Y0 ซึ่งบาง Topic มี 4 บาง Topic มี 5
หน้าตาผลลัพธ์ที่ต้องการ
ผลลัพธ์ที่อยากได้ เราอยากเอา Topic ทั้งหมดขึ้นเป็นหัวตารางไล่ไปทางด้านขวา และหุ้นตัวนึง 1 บรรทัดคือข้อมูล 1 ปี ดังนั้นถ้ามีทั้งหมด 5 ปี หุ้นตัวนึงจะมี 5 บรรทัด
เริ่มกำจัดความเน่าเฟะ
สร้าง Topic แยกออกมาให้ได้
หลังจากสั่ง Get Data from Table/Range เพื่อเอาข้อมูลเข้าสู่ Power Query
ก่อนอื่น เราต้องคิดว่า ถ้าเราอยากเอา Topic ไปทำเป็นหัวตาราง เราต้องสั่ง Pivot เอา Topic ขึ้นไป
และการจะทำ Pivot ได้ ก็ต้องมีคอลัมน์ Topic ขึ้นมาโดยเฉพาะซะก่อน โดย Topic จะต้องถมค่าแบบนี้ให้ได้
การจะถมค่าได้ เราต้องเอาหัว Topic แต่ละบรรทัดมาให้ได้ก่อน แล้วค่อย Fill Down ลงมา
แล้วการจะได้หัว Topic มาเราก็ต้องรู้ให้ได้ว่าอันไหนคือหัว Topic อันไหนไม่ใช่
จากที่ลองไล่ดูแล้ว การจะได้หัว Topic มา น่าจะต้องดูว่าข้อมูลเป็นข้อความรึเปล่า? ถ้าเป็นข้อความน่าจะเป็นหัว Topic
ข้อมูลในคอลัมน์ Data จริงๆ มันก็เป็นข้อความหมดแหละ แค่เป็นตัวที่หน้าตาแบบข้อความจริงๆ กับข้อความที่หน้าตาเหมือนตัวเลข ดังนั้นเราจะลองบังคับขืนใจให้มันเป็นตัวเลขดูว่ามันยอมมั้ย? ถ้ายอมแสดงว่าหน้าตามันเป็นตัวเลขได้
ดังนั้นเราจะสั่ง Duplicate Column Data ออกมาอันนึงก่อน โดยคลิ๊กขวาที่คอลัมน์ Data แล้ว Duplicate Column จากนั้นสั่งแปลงเป็น Decimal Number ซะ
จะพบว่าอันไหนพอจะแปลงเป็นตัวเลขได้ มันก็จัดให้เรียบร้อย อะไรที่ทำไม่ได้ก็ค้างเป็น Error
ถ้าไล่ดูจะเห็นว่ายังมีประเด็นค้างอยู่อีก 2 ตัว คือ วันที่ กับค่า N/A
เนื่องจากค่า N/A ยังไงก็ใช้ไม่ได้ ดังนั้นผมจะย้อน Step กลับไปก่อนจะ Duplicated Column แล้วสั่ง Replace Value (Insert Step) แล้วทำให้ N/A ให้เป็น null ซะ
จากนั้นสั่ง Duplicate คอลัมน์ Data ออกมา เพื่อจัดการแปลงเป็นวันที่ซะ โดยใช้ Using Locale เป็น Thai (เพราะวันที่ที่เป็น text นั้นเป็นรูปแบบไทย)
จะเห็นว่ามันออกมาเป็นวันที่ได้แล้ว แต่ว่าดันติดวันที่เกินๆ มาด้วย (ด้วยความฉลาดที่มากเกินไป ดันมองว่าทศนิยมบางตัวเป็นวันที่ได้ 555)
เพื่อให้จัดการค่าง่ายขึ้นผมจะ Replace Error ใน Data-Copy และ Data-Copy.1 ด้วย null ทั้งหมด
จากนั้นผมสั่ง Conditional Column เพื่อให้เลือกเอา Data ให้เหลือคอลัมน์เดียว นั่นคือ ได้ Data Copy ว่าง ให้เอาจาก Data-Copy.1 แทน
จะได้แบบนี้ ซึ่งดีขึ้นมาก
ดังนั้นบรรทัดที่ยังเป็น null ในคอลัมน์ NumData จะตรงกับ Topic ที่อยากได้ในคอลัมน์ Data พอดีเลย ดังนั้นเราจะใช้ Conditional Column ได้
สุดท้ายจะได้แบบนี้
คราวนี้เราก็ Fill Down คอลัมน์ Topic ได้
จากนั้นเลือกเก็บไว้แค่คอลัมน์ Symbol, Topic และ NumData พอ ด้วยการคลิ๊กเลือก 3 คอลัมน์ที่ต้องการแล้ว Remove Other Column
จากนั้นเราสามารถ Filter เอาบรรทัด null ใน NumData ทิ้งได้เลย
แต่จากการตรวจดู Data พบว่า บาง Topic ดันมี 4 ตัวบ้าง 5 ตัวบ้าง (ซึ่งไม่แปลก เพราะบางค่าของปีล่าสุดจะยังไม่มี) แต่ดันมี Topic ที่มี 3 ตัวด้วย! ซึ่งน่าจะเกิดจากการที่เดิมเป็น N/A แล้วผมสั่งให้เป็น Null
กลับไปแก้ไข Step เก่าให้รัดกุมขึ้น
ดังนั้นการ Replace ให้ N/A เป็น null ก่อนหน้านี้อาจไม่ใช่วิธีที่ดีแล้ว ดังนั้นเราจะไปแก้ให้ Replace N/A เป็นเลขซักตัวนึงที่เรามั่นใจว่าไม่มีทางใช่ข้อมูลจริงดีกว่า เช่น -99999
คราวนี้เราจะได้บรรทัดกลับมาครบตามที่ควรจะเป็นแล้ว (และเรียงถูกต้องตาม sequence เดิม)
แล้วเราค่อย Replace -99999 ของเราด้วย null ใหม่อีกที
สร้างเลข Running ตาม Topic
คราวนี้เราต้องการจะสร้างเลข Running 1,2,3,4,5 ตาม Topic แต่ละตัว (โดยบางตัวอาจมี 4, บางตัวอาจมี 5)
ถ้าเรากด Add Index คอลัมน์ตรงๆ มันจะไม่ Reset ใหม่ตาม Topic แต่เราจะได้ Code ออกมาตามนี้
= Table.AddIndexColumn(#"Replaced Value1", "Index", 1, 1) = Table.AddIndexColumn(ชื่อ Table ,ชื่อคอลัมน์,เลขตั้งต้น,เพิ่มทีละ)
ซึ่งเดี๋ยวเราจะจำเอาไว้เลียนแบบตอนทำเรื่อง Group by ต่อไป
เพื่อให้เราสามารถ Add Index เฉพาะกลุ่มได้ ดังนั้นเราจะใช้ Group By แบบ All Row มาช่วย ดังนี้
เราจะได้ผลลัพธ์ออกมาเป็น Table ซึ่งถ้าคลิ๊กดูจะเป็น Table ที่มีครบทุกคอลัมน์เลย แต่มีการ Group ให้เหลือตามที่เรา Group By เท่านั้น
ซึ่งที่เราจะทำคือเราจะ Add Index คอลัมน์ โดยการใส่ Custom Function แบบนี้
=Table.AddIndexColumn(ชื่อ Table ,ชื่อคอลัมน์,เลขตั้งต้น,เพิ่มทีละ)
=Table.AddIndexColumn([Data],"running",1,1)
ซึ่งในคอลัมน์ NewData เราจะได้ Table ใหม่ ซึ่งมีคอลัมน์ running เพิ่มขึ้นมา
แต่ถ้าเราอยากให้ไล่จาก -4,-3,-2,-1,0 แทน 0,1,2,3,4 ก็ต้องแก้สูตรเป็น
=Table.AddIndexColumn([Data],"running",-4,1)
คราวนี้เราจะลบคอลัมน์ Data ทิ้ง เพราะไม่ใช้แล้ว
หลังจากนั้นกด Expand คอลัมน์ NewData ออกมาโดยเอาแค่ NumData กับ Running ดังรูป
เราจะสั่ง Pivot คอลัมน์ Topic ไปเป็นหัวตาราง แต่ว่าข้อมูลมันจะยัง Sum ไม่ได้เพราะยังไม่ได้เปลี่ยน NumData ให้เป็นตัวเลข
ดังนั้นให้เปลี่ยนประเภทข้อมูล NumData ให้เป็นตัวเลขก่อนครับ (ถึงจะเลือกการ Sum ใน Step ถัดไปได้)
จากนั้นค่อยเลือกคอลัมน์ Topic แล้วสั่ง Pivot Column
ผลลัพธ์จะออกมาเป็นแบบที่อยากได้แล้ว
ความเน่าเฟะที่ยังหลงเหลือ
แต่ถ้าตรวจดูความเรียบร้อย ดันมีคอลัมน์งอกเกินมา ซึ่งเป็นผลมาจาก Symbol บางตัว
ดังนั้นต้องย้อน Step กลับไปดูว่าพลาดตรงไหน
จะพบว่า ดันมี Text จำพวก N/A ที่เราตั้งใจแปลงเป็น -99999 แต่ดันมี Text อื่นอีก เช่น N.A. และ –
ดังนั้นเราต้องย้อน Step กลับไป Replace Value ให้ N.A. และ – เป็น -99999 ด้วย (แบบ Insert Step นะ)
จากนั้นก็ Replace – ด้วย -99999 อีกที แต่ให้ติ๊กว่าต้องเจอแบบ Entire Cell Content ด้วยนะ ไม่งั้นมันแทนเครื่องหมายติดลบด้วยซวยเลย
ถ้าเรากลับไปดู Step สุดท้าย จะพบว่าคอลัมน์ที่งอกเกินมาได้หายไปแล้ว
จัดการวันที่
เหลือปัญหาสุดท้ายคือ Data Type ของวันที่งบการเงิน แค่กดเปลี่ยน Data Type เป็น Date ก็จบเลย เพราะเลขเป็น 4 หมื่นกว่าอยู่แล้ว
แก้คอลัมน์ Running ให้เป็น Year
เดิม Running เราเป็น -4,-3,-2… สมมติว่าเราจะทำให้เป็น Y-4, Y-3, Y-2 ก็ทำได้
ให้ไปที่คอลัมน์ Running -> Transform -> Format -> Add Prefix แล้วใส่คำว่า Y
จากนั้นเปลี่ยนชื่อคอลัมน์เป็น Year ซะก็จบละ
จบแล้ว สำเร็จ!!
ในที่สุด เราก็ได้ฐานข้อมูลที่ต้องการแล้ว ดังนั้นกด Close & Load to.. ออกมาเป็น Table หรือจะเอาเข้า Pivot Table เลยก็ย่อมได้
เป็นอย่างไรบ้างกับการต่อสู้อันยาวนานกับข้อมูลขยะอันเน่าเฟะ อาจมีขั้นตอนเยอะซักหน่อย แต่คิดว่าเป็นประโยชน์กับทุกคนแน่นอนครับ ใครสงสัยตรงไนก็ post ถามได้เลยนะครับ