นโยบายการจัดการความรู้ มหาวิทยาลัยสงขลานครินทร์ 1.ให้ใช้เครื่องมือการจัดการความรู้ผลักดัน คุณภาพคน และกระบวนทำงาน 2.ส่งเสริมการแลกเปลี่ยนประสบการณ์การทำงาน จากหน้างาน 3.ส่งเสริมให้มีเวทีเรียนรู้ร่วมกัน

Our Shangri-La
Ico64
Kittisakdi Choomalee

ภาควิชาเวชศาสตร์ชุมชน คณะแพทยศาสตร์ มหาวิทยาลัยสงขลานครินทร์
เครือข่าย
สมาชิก · ติดตาม: 0 · ผู้ติดตาม: 16

อ่าน: 1589
ความเห็น: 0

ก้าวย่าง ทางเดิน ลืมเลือนคืนวัน ดั้นด้นไป: KML vs R ยกที่ ๗

เข้าเรื่อง เข้าเรื่อง รีบจบ รีบไป

ผมตัดสินใจว่าจะจบบันทึกในซีรี่ย์ kml vs R ไว้ที่บันทึกนี้นะครับ ยิ่งเขียนก็ยิ่งเข้าป่าลึกเข้าไปทุกทีจนหาทางออกไม่เจอแล้ว เอาเป็นว่าหักมุมเข้าเรื่องกันเลยครับ

กว่าจะจัดการดึงข้อมูล kml ออกมาสำเร็จนั้นผมต้องคลำไปคลำมากับเรื่องการจัดเก็บข้อมูลของโปรแกรม R เสียยกใหญ่ หรือเล่นแร่แปรธาตุกับวัตถุในโปรแกรม R เสียยกใหญ่กว่าจะไปถูกที่ถูกทาง

ผมเองก็เข้ารกเข้าพงไปนานเหมือนกัน

จากบันทึกก่อนหน้านี้ทำให้เราทราบกันแล้วว่าเมื่อเราดึงค่าพิกัดมาจากแฟ้มข้อมูล kml ได้แล้วนั้น ข้อมูลจะถูกเก็บไว้ในวัตถุที่มี class เป็น list เมื่อผมลองใช้ฟังก์ชัน coordinates() เพื่อแปลงค่าพิกัดที่เก็บไว้ในวัตถุ test1 (ที่มี class เป็น list นั้น) โปรแกรม R แจ้งข้อความผิดพลาดให้ว่า

> test100 <- coordinates(test1)
Error in .checkNumericCoerce2double(as.data.frame(obj)) :
  cannot retrieve coordinates from non-numeric elements

ผมลองอ่านข้อความที่แสดงความผิดพลาดจากการใช้ฟังก์ชันพอจะทราบว่าในฟังก์ชัน coordinates() นั้นมีการตรวจสอบข้อมูลที่จะนำมาแปลงเป็นพิกัด (coordinates) นั้นเป็นตัวเลขหรือไม่ ถ้าใช่ก็จะทำการแปลงให้ตัวเลขนั้นเป็นแบบ double (.checkNumericCoerce2double) โดยก่อนหน้านี้จะทำการแปลงวัตถุที่มีค่าพิกัดอยู่ (ในที่นี้คือ test1) ให้เป็นวัตถุที่มี class เป็น data frame (as.data.frame(obj))

โปรแกรม R ไม่สามารถที่จะดึงข้อมูลพิกัดมาจากวัตถุที่ไม่มีการจัดเก็บข้อมูลแบบตัวเลขได้ (test1 เป็น list อยู่นั่นเอง)

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

เรื่องแรกก็คือต้องทำข้อมูลที่เก็บอยู่ใน test1 ให้เป็นตัวเลขเสียก่อนก่อน และหรือต้องทำวัตถุที่เก็บข้อมูลพิกัดที่ได้จากการใช้ฟังก์ชัน getKMLcoordinates() ที่มี class เป็น list ให้อยู่ในรูปของ data frame หรือ vector ???

จากตัวอย่างในบันทึกก่อนๆ ทำให้เราทราบว่าหากต้องการแปลงข้อมูลให้อยู่ในรูปของกรอบข้อมูล (data frame) นั้นเราใช้ฟังก์ชัน data.frame() ในการเปลี่ยนวัตถุให้มี class เป็น data frame

ผมก็ลองดูตามที่คิดไว้ครับ

> test1.dat <- data.frame(test1)
> class(test1.dat)
[1] "data.frame"

> test1.dat
                            X1                           X2                           X3                           X4                           X5
1 100.07497, 15.23082, 0.00000 100.06355, 15.22436, 0.00000 100.05911, 15.21749, 0.00000 100.05066, 15.21275, 0.00000 100.04680, 15.20974, 0.00000

---

1 100.9878, 13.7753, 0.0000 100.98056, 13.71931, 0.00000 100.97695, 13.69499, 0.00000 100.9710, 13.6716, 0.0000 100.95334, 13.62583, 0.00000
                          X104 X105 X106
1 100.88918, 13.46591, 0.00000        NA

เห็นผลลัพธ์ออกมาแล้วใช่ไหมครับ เมื่อเรียกดูค่าที่เก็บไว้ใน test1.dat หรือ test1 ที่ถูกเปลี่ยนจาก list มาให้เป็น data frame นั้น แสดงขอมูลตัวเลขออกมาให้เราเห็นแล้ว นั่นคือใน data frame test1.dat นั้นประกอบไปด้วยตัวแปร X1 X2 X3 ... X106 และในตัวแปรแต่ละตัวนั้นประกอบไปด้วยข้อมูลที่เป็นตัวเลข 3 ชุดด้วยกัน ค่าที่ 3 จะเหมือนกันทุกตัวแปรคือเท่ากับ 0.00000

ผมลองใช้ฟังก์ชัน coordinates() กับ test1.dat ที่เป็น data frame ก็พบว่า

> test1.dat.cor <- coordinates(test1.dat)
Error in .checkNumericCoerce2double(obj) :
  cannot retrieve coordinates from non-numeric elements

ไม่สำเร็จเช่นเดิมครับ แต่ข้อความที่แสดงข้อผิดพลาดเปลี่ยนไปนิดนึง

เปลี่ยนไปตรงไหนบ้างครับ?

มาถึงขั้นตอนนี้แล้วฟังก์ชัน coordinate() ไม่มีการตรวจสอบว่าวัตถุที่มีค่าพิกัดอยู่เป็น data frame หรือไม่ มีเพียงทดสอบว่าเป็นข้อมูลตัวเลขหรือไม่ถ้าใช่จะแปลงข้อมูลให้เป็นแบบ double (.checkNumericCoerce2double(obj))

สุดท้ายข้อมูลที่เป็น data frame ในลักษณะนี้ก็ยังไม่ใช่รูปแบบที่ฟังก์ชัน coordinates() จะดึงค่าพิกัดออกมาได้เช่นเดิม

ผมลองตรวจสอบ class ของ test1.dat ดูอีกรอบ

> class(test1.dat)
[1] "data.frame"
> test1.dat[1]
                            X1
1 100.07497, 15.23082, 0.00000
> class(test1.dat[1])
[1] "data.frame"

test1.dat มี class เป็น data frame

ให้โปรแกรม R แสดงค่าในตำแหน่งที่ 1 ของวัตถุ test1.dat ออกมา ได้ผลเป็น

                            X1
1 100.07497, 15.23082, 0.00000

ตรวจสอบดูว่าค่าในตำแหน่งที่ 1 ของวัตถุ test1.dat (test1.dat[1]) มี class เป็นอะไร

ผลที่ได้โปรแกรม R ตอบกลับมาว่าค่าในตำแหน่งที่ 1 ของวัตถุ test1.dat นั้นมี class เป็น data frame

วัตถุ test1.dat เป็น data frame ที่บรรจุไว้ด้วย data frame ภายใน?

> test1.dat.1 <- test1.dat[1]
> class(test1.dat.1)
[1] "data.frame"
> test1.dat.1
                            X1
1 100.07497, 15.23082, 0.00000

> test1.dat.1.cor <- coordinates(test1.dat.1)
Error in .checkNumericCoerce2double(obj) :
  cannot retrieve coordinates from non-numeric elements

ยังไม่ได้อยู่ดีครับ

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

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

จากที่เราทราบมาตั้งแต่บันทึกแรกๆ ของซีรี่ย์นี้ว่า หลังจากที่เราใช้ฟังก์ชัน getKMLcoordinates() ดึงเอาพิกัดจากแฟ้มข้อมูล kml มาเก็บไว้ในวัตถุในโปรแกรม R ที่ชื่อ test1 ไปแล้วนั้น

วัตถุ test1 มี class เป็น list ภายในวัตถุ test1 ประกอบไปด้วยข้อมูลพิกัดของ floodway จำนวน ๒ เส้นด้วยกัน (ผมไม่ย้อนไปแบบละเอียดแล้วนะครับ) สายแรกทางฝั่งตะวันตกมีจุดพิกัดอยู่ทั้งหมด ๖๗ พิกัด และทางฝั่งตะวันออกมีพิกัดอยู่ทั้งหมด ๑๐๕ พิกัด

เพื่อเป็นการให้ง่ายต่อการจัดการข้อมูล ผมจะดึงข้อมูลพิกัดมาเฉพาะ floodway ทางฝั่งตะวันตกที่มีจุดพิกัดอยู่จำนวน ๖๗ พิกัดมาใช้เป็นตัวอย่าง

คำว่า ๖๗ พิกัดในที่นี้หมายถึง ๑ จุดพิกัดมีค่า X coordinates Y coordinates และ z coordinates ในที่นี้ z coordinates มีค่าเป็น ๐ ทุกพิกัด (๒ มิติ) ดังนั้น ๑ จุดพิกัดจะประกอบไปด้วยตัวเลข ๓ ชุดด้วยกัน ตัวเลขตัวสุดท้ายของแต่ละชุด (จุดพิกัด) จะมีค่าเป็น ๐

ข้อมูลใน test 1 ที่เป็น list จะเก็บข้อมูลพิกัดแยกเป็น ๖๗ ชุดข้อมูล (๑ ชุดข้อมูลมี ๓ ค่า)

ในความเป็นจริงแล้วจะมีชุดข้อมูลอีก ๒ ชุดที่รวมอยู่ในแต่ละชุดพิกัดของ floodway แต่ละสาย แต่ข้อมูลทั้ง ๒ ชุดนี้ไม่ใช่ข้อมูลจุดพิกัด ดังนั้นชุดข้อมูลจริงของ floodway สายตะวันตกจึงมีทั้งหมด ๖๙ ชุด เป็นชุดพิกัด ๖๗ ชุด ไม่ใช่ข้อมูลพิกัดอีก ๒ ชุดข้อมูล

ในการเลือกข้อมูลจุดพิกัดเราจึงต้องดึงข้อมูลมาเฉพาะข้อมูลพิกัด ๖๗ ชุดเท่านั้น

จากบันทึกก่อนหน้านี้ มีฟังก์ชันที่ช่วยให้เราแปลงวัตถุที่มี class เป็น list กลายเป็น numeric นั่นคือฟังก์ชัน unlist()

เราลองมาดูคำสั่งนี้กันครับ

> test1.num <- unlist(test1)
> class(test1.num)
[1] "numeric"
> test1.num
  [1] 100.07497  15.23082   0.00000 100.06355  15.22436   0.00000 100.05911  15.21749   0.00000 100.05066  15.21275   0.00000 100.04680  15.20974   0.00000
--- ลบข้อมูลออกบางส่วน
[511]   0.00000 100.88918  13.46591   0.00000        NA

  • ให้วัตถุชื่อ test1.num เก็บค่าที่เกิดจากการแปลงค่าข้อมูลที่เก็บอยู่ในวัตถุ test1 โดยแปลงค่าข้อมูลที่มี class เป็น list ให้เป็นข้อมูลที่มี class เป็น numeric โดยใช้ฟังก์ชัน unlist()
  • ตรวจสอบ class ของวัตถุ test1.num
  • โปรแกรม R ตอบกลับมาว่าวัตถุ test1.num มี class เป็น numeric
  • แสดงค่าที่เก็บในวัตถุ test1.num
  • ค่าที่บรรจุอยู่ในวัตถุ test1.num มีจำนวน ๕๑๕ ค่า ค่าสุดท้ายจะเป็น "NA"

NA ในโปรแกรม R ก็คือ Not Available หรือมีค่าเป็นค่าว่าง หรือเป็นค่าสูญหาย (Missing Value) นั่นเอง

แต่ค่าที่เก็บในวัตถุ test1 ที่มี class เป็น list นั้นมีค่าทั้งหมด ๕๑๗ ค่าไม่ใช่ ๕๑๕ ค่าดังผลลัพธ์ที่เกิดจากฟังก์ชัน unlist()

อีก ๒ ค่าหายไปไหน?

หากจำกันได้หากเราลองให้โปรแกรม R แสดงค่าที่อยู่ในวัตถุ test1 ออกมา เราจะพบค่า ๒ ค่าสุดท้ายของแนว floodway แต่ละแนวมีค่าเป็น "Numeric,0" และ "NA" (ค่าพิกัดจะเป็น "Numeric,3")

ค่าที่หายไปคือ "Numeric,0" ส่วน NA นั้นยังอยู่

สิ่งที่เราต้องการก็คือต้องการค่าพิกัด ๖๗ พิกัดแรกของแนว floodway ฝั่งตะวันตก

แต่ละชุดพิกัดจะมีค่าพิกัด ๓ ค่า ค่าที่ ๓ จะมีค่าเป็น ๐ (ยังจำกันได้นะครับ) ดังนั้นข้อมูล ๖๗ พิกัดจึงต้องเป็นค่าตัวเลขทั้งหมด ๖๗x๓ ค่าหรือเท่ากับ ๒๐๑ ค่า

ดังนั้นข้อมูลที่เราต้องการคือข้อมูล ๒๐๑ ข้อมูลแรกจากผลลัพธ์ของฟังก์ชัน unlist

ยังจำได้ใช่ไหมครับว่าหากเราต้องการเลือกหรือแสดงค่าในตำแหน่งต่างๆ ในวัตถุเราจะใช้เครื่องหมาย [ ] และตัวเลขในการระบุตำแหน่งในวัตถุ

ในที่นี้ผลลัพธ์จากฟังก์ชัน unlist() หรือวัตถุ test1.num มี class เป็น numeric (vector) หรือเป็นข้อมูลมิติเดียว

test1.num[1] หมายถึงแสดค่าตำแหน่งแรก (ค่าแรก) ที่เก็บในวัตถุ test1.num (ค่าที่เก็บในวัตถุ test1.num จะเรียงต่อกันเป็นแถวเดียว)

และเราทราบว่าหากต้องการดูค่าในตำแหน่งที่ 1 ถึง 201 เราจะใช้การเขียนตำแหน่งเป็น [1:201]

ดังนั้นหากเราต้องการดึงค่า ๒๐๑ ค่าแรกที่เก็บในวัตถุ test1.num เราต้องระบุตำแหน่งเป็น test1.num[1:201] จะได้เป็น

> test1.num[1:201]
  [1] 100.07497  15.23082   0.00000 100.06355  15.22436   0.00000 100.05911  15.21749   0.00000 100.05066  15.21275   0.00000 100.04680  15.20974   0.00000
 --- ลบข้อมูลบางส่วนออก
[196]  99.89306  14.40356   0.00000 100.01962  13.37173   0.00000

จากความรู้เดิมที่หากเราต้องการสร้างวัตถุที่เป็น numeric vectorเราใช้ฟังก์ชัน c() ในการรวมค่าข้อมูลเข้าด้วยกัน

จากควาามรู้ข้างต้นทั้งหมดเรารวบฟังก์ชันต่างๆ ข้างต้นมาเขียนเป็นบรรทัดเดียวในโปรแกรม R โดยให้ข้อมูลจุดพิกัดทั้ง ๖๗ พิกัด (๒๐๑ ค่า) เก็บไว้ในวัตถุชื่อ test1.67.num

> test1.67.num <- c(unlist(test1))[1:201]
> class(test1.67.num)
[1] "numeric"
> test1.67.num
  [1] 100.07497  15.23082   0.00000 100.06355  15.22436   0.00000 100.05911  15.21749   0.00000 100.05066  15.21275   0.00000 100.04680  15.20974   0.00000
--- ตัดข้อมูลออกบางส่วน
[196]  99.89306  14.40356   0.00000 100.01962  13.37173   0.00000

มาถึงตรงนี้คงต้องพักยกอีกสักรอบนะครับ

ขั้นตอนต่อไปหลังจากนี้ก็คือการทำข้อมูลที่เป็น numeric vector หรือข้อมูลที่เป็นมิติเดียวให้เป็นข้อมูล ๒ มิติ

นึกกันออกแล้วใช่ไหมครับว่าทำยังไง

ให้นึกถึงว่าค่าพิกัดแต่ละจุดประกอบไปด้วยข้อมูล ๓ ค่า หรือคิดง่ายๆ ว่า ฝั่งสดมภ์จะต้องมี ๓ สดมภ์ (x, y และ z) ส่วนแถวต้องมี ๖๗ แถว แต่ข้อมูลตอนนี้ที่เรามี ข้อมูลเรียงต่อกันไปทั้ง ๖๗ ชุดเป็นแถวเดียว

เราเอง


หมวดหมู่บันทึก: บริการวิชาการ
สัญญาอนุญาต: ซีซี: แสดงที่มา-ไม่ใช้เพื่อการค้า-อนุญาตแบบเดียวกัน Cc-by-nc-sa
สร้าง: 29 มีนาคม 2555 22:59 แก้ไข: 29 มีนาคม 2555 22:59 [ แจ้งไม่เหมาะสม ]
ดอกไม้
สมาชิกที่ให้กำลังใจ: Ico24 คนธรรมดา.
สมาชิกที่ให้กำลังใจ
 
Facebook
Twitter
Google

บันทึกอื่นๆ

ความเห็น

ไม่มีความเห็น

ร่วมแสดงความเห็นในหน้านี้

ชื่อ:
อีเมล:
IP แอดเดรส: 3.228.11.9
ข้อความ:  
เรียกเครื่องมือจัดการข้อความ
   
ยกเลิก หรือ