Category: R

  • data.table: แนะนำ 3 ส่วนวิธีใช้งาน package ทรงพลัง เพื่อทำงานกับข้อมูลขนาดใหญ่อย่างมีประสิทธิภาพและรวดเร็ว ในภาษา R แบบครบ — ตัวอย่างการทำงานกับข้อมูลเที่ยวบินจาก flights dataset

    data.table: แนะนำ 3 ส่วนวิธีใช้งาน package ทรงพลัง เพื่อทำงานกับข้อมูลขนาดใหญ่อย่างมีประสิทธิภาพและรวดเร็ว ในภาษา R แบบครบ — ตัวอย่างการทำงานกับข้อมูลเที่ยวบินจาก flights dataset

    R ได้ชื่อว่าเป็น “statistical programming language” เพราะออกแบบมาเพื่อทำงานกับ data โดยเฉพาะ

    ภาษา R มี packages มากมายที่รองรับการทำงานกับ data ในรูปแบบตาราง (tabular data) หรือ data frame อย่างตัวอย่างในภาพ:

    ตัวอย่าง data frame: flights dataset

    หนึ่งใน packages ที่ได้รับความนิยมในการทำงานกับ data frame โดยเฉพาะงาน data science ได้แก่ data.table

    data.table เป็น package สำหรับ data manipulation ที่มีจุดเด่น 3 อย่าง คือ:

    1. ใช้งานง่าย (แม้จะมีการเขียนที่แตกต่างจาก functions ทั่วไป แต่มี syntax ที่ตายตัว)
    2. ประมวลผลเร็วและประหยัด resource เพราะ data.table optimises code ที่เราเขียน
    3. รองรับการทำงานกับ data ขนาดใหญ่ (เช่น data ที่ใช้ RAM ขนาด 10 ถึง 100 GB ในการประมวลผล)

    ในบทความนี้ เราจะมาดูวิธีการใช้งาน data.table แบบครบจบใน 3 ส่วนกัน:

    1. การใช้งาน data.table เบื้องต้น (syntax และ arguments)
    2. การใช้งาน data.table ขั้นสูง (combining และ chaining)
    3. Special symbols ใน data.table

    ถ้าพร้อมแล้ว มาเริ่มกันเลย


    1. 🏁 Get Started With data.table
    2. ✈️ Example Dataset: flights
      1. 1️⃣ Intro to flights
      2. 2️⃣ Get flights
    3. ✍️ Syntax: DT[i, j, by]
    4. 🍦 1st Argument: i
      1. 1️⃣ Select Rows
      2. 2️⃣ Filter
      3. 3️⃣ Sort
    5. 🧮 2nd Argument: j
      1. 1️⃣ Select Columns
      2. 2️⃣ Compute
      3. 3️⃣ Create Columns
    6. 🤝 3rd Argument: by
    7. 🔗 Combining & Chaining
      1. 1️⃣ Combining
      2. 2️⃣ Chaining
    8. 🍩 Special Symbols
      1. 1️⃣ .N
      2. 2️⃣ .SD
      3. 3️⃣ .SDcols
    9. 😎 Conclusion
    10. 🎒 Learn More About data.table
      1. 😺 GitHub
      2. 📚 อ่านเพิ่มเติมเกี่ยวกับ data.table
      3. 📑 Cheat Sheets ในการใช้งาน data.table
    11. 📃 References
    12. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    🏁 Get Started With data.table

    ในการเริ่มต้นใช้งาน data.table เราจะต้องทำ 2 อย่าง ได้แก่:

    1. ติดตั้ง data.table (ทำครั้งแรกครั้งเดียว)
    2. โหลด data.table (ทำทุกครั้งที่เริ่ม session ใหม่)
    # Install data.table
    install.packages("data.table")
    
    # Load data.table
    library(data.table)
    

    เมื่อทำทั้ง 2 อย่างนี้แล้ว เราก็พร้อมที่จะใช้งาน data.table กันแล้ว


    ✈️ Example Dataset: flights

    1️⃣ Intro to flights

    ในบทความนี้ เราจะมาดูตัวอย่างการใช้ data.table กับ flights ซึ่งมีข้อมูลเที่ยวบินที่ออกจาก New York City ในปี ค.ศ. 2014 เช่น:

    • วันที่
    • สนามบินต้นทางและปลายทาง
    • ระยะเวลาที่เที่ยวบิน delay
    • ระยะเวลาบิน
    • ระยะทาง

    Note: ดูรายละเอียดทั้งหมดของ dataset ได้ที่ GitHub

    .

    2️⃣ Get flights

    เราสามารถเริ่มใช้งาน flights ใน 2 ขั้นตอน:

    ขั้นที่ 1. Download ไฟล์จาก link โดยไฟล์ที่ได้จะเป็น CSV (comma-separated values):

    ขั้นที่ 2. Import ข้อมูลเข้าใน R ด้วย fread() (”fast read”) ซึ่งเป็น function สำหรับโหลดข้อมูลของ data.table:

    # Import the dataset
    flights <- fread("flights14.csv")
    

    เราสามารถดูตัวอย่างข้อมูลได้ด้วย head():

    # Preview the dataset
    head(flights)
    

    ผลลัพธ์:

        year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
       <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
    1:  2014     1     1        14        13      AA    JFK    LAX      359     2475     9
    2:  2014     1     1        -3        13      AA    JFK    LAX      363     2475    11
    3:  2014     1     1         2         9      AA    JFK    LAX      351     2475    19
    4:  2014     1     1        -8       -26      AA    LGA    PBI      157     1035     7
    5:  2014     1     1         2         1      AA    JFK    LAX      350     2475    13
    6:  2014     1     1         4         0      AA    EWR    LAX      339     2454    18
    

    ✍️ Syntax: DT[i, j, by]

    การใช้งาน data.table ประกอบด้วย 4 ส่วน ดังนี้:

    DT[i, j, by]
    1. DT คือ dataset ที่เราต้องการใช้งาน
    2. i ใช้ทำงานกับ rows
    3. j ใช้ทำงานกับ columns
    4. by ใช้จับกลุ่มข้อมูล

    เราไปดูรายละเอียดการใช้งาน i, j, และ by กัน


    🍦 1st Argument: i

    เราสามารถใช้งาน i ได้ 3 อย่าง:

    1. Select rows: เลือก rows ที่ต้องการ
    2. Filter: กรองข้อมูล
    3. Sort: จัดลำดับข้อมูล

    .

    1️⃣ Select Rows

    เราสามารถใช้ i เพื่อเลือก rows ได้ 3 แบบ:

    1. เลือก 1 row
    2. เลือกหลาย rows
    3. คัด rows ที่ไม่ต้องการออก

    .

    แบบที่ #1. เลือก 1 row

    เช่น เลือก row ที่ 5 จาก flights:

    # Select a row
    flights[5]
    

    ผลลัพธ์:

        year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
       <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
    1:  2014     1     1         2         1      AA    JFK    LAX      350     2475    13
    

    .

    แบบที่ #2 – เลือกหลาย rows

    ซึ่งเราทำได้โดยการใช้ vector เช่น เลือก rows 1 ถึง 10:

    # Select a range of rows
    flights[1:10]
    

    ผลลัพธ์:

         year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
        <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
     1:  2014     1     1        14        13      AA    JFK    LAX      359     2475     9
     2:  2014     1     1        -3        13      AA    JFK    LAX      363     2475    11
     3:  2014     1     1         2         9      AA    JFK    LAX      351     2475    19
     4:  2014     1     1        -8       -26      AA    LGA    PBI      157     1035     7
     5:  2014     1     1         2         1      AA    JFK    LAX      350     2475    13
     6:  2014     1     1         4         0      AA    EWR    LAX      339     2454    18
     7:  2014     1     1        -2       -18      AA    JFK    LAX      338     2475    21
     8:  2014     1     1        -3       -14      AA    JFK    LAX      356     2475    15
     9:  2014     1     1        -1       -17      AA    JFK    MIA      161     1089    15
    10:  2014     1     1        -2       -14      AA    JFK    SEA      349     2422    18
    

    หรือเลือก rows 1, 3, 5, 7, และ 9:

    # Select multiple rows at interval
    flights[c(1, 3, 5, 7, 9)]
    

    ผลลัพธ์:

        year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
       <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
    1:  2014     1     1        14        13      AA    JFK    LAX      359     2475     9
    2:  2014     1     1         2         9      AA    JFK    LAX      351     2475    19
    3:  2014     1     1         2         1      AA    JFK    LAX      350     2475    13
    4:  2014     1     1        -2       -18      AA    JFK    LAX      338     2475    21
    5:  2014     1     1        -1       -17      AA    JFK    MIA      161     1089    15
    

    .

    แบบที่ #3 – คัด rows ที่ไม่ต้องการออก

    ซึ่งเราสามารถทำได้ 2 แบบ คือ:

    1. ใช้ -
    2. ใช้ !

    เช่น คัด row ที่ 1 ออก โดยใช้ -:

    # Deselect a row
    flights[-1]
    

    หรือใช้ !:

    # Deselect a row
    flights[!1]
    

    โดยทั้งสองแบบจะให้ผลลัพธ์แบบเดียวกัน แบบนี้:

             year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
            <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
         1:  2014     1     1        -3        13      AA    JFK    LAX      363     2475    11
         2:  2014     1     1         2         9      AA    JFK    LAX      351     2475    19
         3:  2014     1     1        -8       -26      AA    LGA    PBI      157     1035     7
         4:  2014     1     1         2         1      AA    JFK    LAX      350     2475    13
         5:  2014     1     1         4         0      AA    EWR    LAX      339     2454    18
        ---                                                                                    
    253311:  2014    10    31         1       -30      UA    LGA    IAH      201     1416    14
    253312:  2014    10    31        -5       -14      UA    EWR    IAH      189     1400     8
    253313:  2014    10    31        -8        16      MQ    LGA    RDU       83      431    11
    253314:  2014    10    31        -4        15      MQ    LGA    DTW       75      502    11
    253315:  2014    10    31        -5         1      MQ    LGA    SDF      110      659     8
    

    .

    2️⃣ Filter

    นอกจากการเลือก rows เรายังสามารถใช้ i เพื่อกรอง data ได้ 3 แบบ:

    1. กรองโดยใช้ 1 เงื่อนไข
    2. กรองโดยใช้หลายเงื่อนไข
    3. กรองโดยใช้ helpers

    .

    แบบที่ #1 – กรองข้อมูลโดยใช้ 1 เงื่อนไข

    เช่น กรอง rows ที่มีระยะทางบิน 500 miles ขึ้นไป:

    # Filter with 1 condition
    flights[distance >= 500]
    

    ผลลัพธ์:

             year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
            <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
         1:  2014     1     1        14        13      AA    JFK    LAX      359     2475     9
         2:  2014     1     1        -3        13      AA    JFK    LAX      363     2475    11
         3:  2014     1     1         2         9      AA    JFK    LAX      351     2475    19
         4:  2014     1     1        -8       -26      AA    LGA    PBI      157     1035     7
         5:  2014     1     1         2         1      AA    JFK    LAX      350     2475    13
        ---                                                                                    
    198323:  2014    10    31        18       -14      UA    EWR    LAS      291     2227    16
    198324:  2014    10    31         1       -30      UA    LGA    IAH      201     1416    14
    198325:  2014    10    31        -5       -14      UA    EWR    IAH      189     1400     8
    198326:  2014    10    31        -4        15      MQ    LGA    DTW       75      502    11
    198327:  2014    10    31        -5         1      MQ    LGA    SDF      110      659     8
    

    .

    แบบที่ #2 – กรองข้อมูลด้วยหลายเงื่อนไข

    เราสามารถเพิ่มเงื่อนไขการกรองได้ด้วย logical operators:

    OperatorMeaning
    &AND
    |OR
    !NOT

    เช่น กรอง rows ที่:

    • มีระยะทางบิน 500 miles ขึ้นไป และ
    • ออกจากสนามบิน LaGuardia (LGA):
    # Filter with multiple conditions
    flights[distance >= 500 & origin == "LGA"]
    

    ผลลัพธ์:

            year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
           <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
        1:  2014     1     1        -8       -26      AA    LGA    PBI      157     1035     7
        2:  2014     1     1        -7        -6      AA    LGA    ORD      142      733     5
        3:  2014     1     1        -7         0      AA    LGA    ORD      143      733     6
        4:  2014     1     1        -8       -17      AA    LGA    ORD      139      733     6
        5:  2014     1     1        -2        15      AA    LGA    ORD      145      733     7
       ---                                                                                    
    63251:  2014    10    31        14       -17      UA    LGA    IAH      200     1416    17
    63252:  2014    10    31        24        -5      UA    LGA    IAH      198     1416     6
    63253:  2014    10    31         1       -30      UA    LGA    IAH      201     1416    14
    63254:  2014    10    31        -4        15      MQ    LGA    DTW       75      502    11
    63255:  2014    10    31        -5         1      MQ    LGA    SDF      110      659     8
    

    .

    แบบที่ #3 – กรองโดยใช้ helpers

    เราสามารถกรองข้อมูลโดยใช้ helpers หรือ operators พิเศษ 3 อย่างนี้:

    HelperForSyntax
    %between%กรองข้อมูลตาม rangecol %between% range
    %like%กรองข้อมูลตาม text patterncol %like% pattern
    %chin%กรองข้อมูลอยู่ใน set ที่กำหนดcol %chin% set

    ตัวอย่าง:

    ใช้ %between% เพื่อกรองข้อมูลที่มีระยะทางบินระหว่าง 500 ถึง 1,000 miles:

    # Filter using %between%
    flights[distance %between% c(500, 1000)]
    

    ผลลัพธ์:

            year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
           <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
        1:  2014     1     1        18        69      AA    JFK    ORD      155      740    17
        2:  2014     1     1        -7        -6      AA    LGA    ORD      142      733     5
        3:  2014     1     1        -7         0      AA    LGA    ORD      143      733     6
        4:  2014     1     1        -8       -17      AA    LGA    ORD      139      733     6
        5:  2014     1     1        -2        15      AA    LGA    ORD      145      733     7
       ---                                                                                    
    79754:  2014    10    31        10        -5      UA    EWR    ORD      110      719     6
    79755:  2014    10    31         5         2      UA    EWR    ORD      132      719    10
    79756:  2014    10    31       427       393      UA    EWR    ORD      100      719    21
    79757:  2014    10    31        -4        15      MQ    LGA    DTW       75      502    11
    79758:  2014    10    31        -5         1      MQ    LGA    SDF      110      659     8
    

    Note: code นี้ให้ผลลัพธ์เดียวกับการเขียน flights[distance >= 500 & distance <= 1000] แต่การใช้ %between% ทำให้ code สั้นและอ่านง่ายกว่า

    .

    ใช้ %like% เพื่อกรองข้อมูลที่สนามบินปลายทางขึ้นต้นด้วย “A” เช่น “ABQ”, “ACK”, “AGS”:

    # Filter using %like%
    flights[dest %like% "^A"]
    

    ผลลัพธ์:

            year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
           <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
        1:  2014     1     1        -1         1      AA    JFK    AUS      232     1521    17
        2:  2014     1     1        -5        16      B6    JFK    AUS      247     1521    20
        3:  2014     1     1        21        21      B6    JFK    AUS      237     1521     9
        4:  2014     1     1        10         4      B6    JFK    ABQ      280     1826    20
        5:  2014     1     1        10        10      DL    LGA    ATL      126      762    18
       ---                                                                                    
    15630:  2014    10    31        50        43      UA    EWR    ATL      113      746    15
    15631:  2014    10    31        -5       -38      UA    EWR    ATL      111      746     5
    15632:  2014    10    31        -5        -2      UA    EWR    AUS      211     1504    15
    15633:  2014    10    31        -9       -15      UA    EWR    ATL      119      746    11
    15634:  2014    10    31        11       -10      UA    EWR    ATL      109      746     8
    

    ใช้ %chin% เพื่อกรองข้อมูลที่สนามบินปลายทาง คือ ATL, LAX, หรือ ORD:

    # Filter using %chin%
    flights[dest %chin% c("ATL", "LAX", "ORD")]
    

    ผลลัพธ์:

            year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
           <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
        1:  2014     1     1        14        13      AA    JFK    LAX      359     2475     9
        2:  2014     1     1        -3        13      AA    JFK    LAX      363     2475    11
        3:  2014     1     1         2         9      AA    JFK    LAX      351     2475    19
        4:  2014     1     1         2         1      AA    JFK    LAX      350     2475    13
        5:  2014     1     1         4         0      AA    EWR    LAX      339     2454    18
       ---                                                                                    
    38827:  2014    10    31        10        -5      UA    EWR    ORD      110      719     6
    38828:  2014    10    31         3       -32      UA    EWR    LAX      320     2454    20
    38829:  2014    10    31         5         2      UA    EWR    ORD      132      719    10
    38830:  2014    10    31       427       393      UA    EWR    ORD      100      719    21
    38831:  2014    10    31        10       -27      UA    EWR    LAX      326     2454    10
    

    .

    3️⃣ Sort

    สุดท้าย เราสามารถใช้ i เพื่อเรียงลำดับข้อมูลได้ 3 แบบ:

    1. Sort ascending (A—Z)
    2. Sort descending (Z—A)
    3. Sort by multiple columns

    .

    แบบที่ #1 – Sort ascending

    เช่น จัดเรียงตามชื่อสนามบินต้นทาง จาก A—Z:

    # Sort ascending
    flights[order(origin)]
    

    ผลลัพธ์:

             year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
            <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
         1:  2014     1     1         4         0      AA    EWR    LAX      339     2454    18
         2:  2014     1     1        -5       -17      AA    EWR    MIA      161     1085    16
         3:  2014     1     1       191       185      AA    EWR    DFW      214     1372    16
         4:  2014     1     1        -1        -2      AA    EWR    DFW      214     1372    14
         5:  2014     1     1        -3       -10      AA    EWR    MIA      154     1085     6
        ---                                                                                    
    253312:  2014    10    31        24        -5      UA    LGA    IAH      198     1416     6
    253313:  2014    10    31         1       -30      UA    LGA    IAH      201     1416    14
    253314:  2014    10    31        -8        16      MQ    LGA    RDU       83      431    11
    253315:  2014    10    31        -4        15      MQ    LGA    DTW       75      502    11
    253316:  2014    10    31        -5         1      MQ    LGA    SDF      110      659     8
    

    .

    แบบที่ #2 – Sorting descending

    เราเรียงข้อมูลแบบ descending (Z—A) ได้ 2 วิธี:

    1. ใช้ decreasing = TRUE
    2. ใช้ -

    เช่น จัดเรียงตามชื่อสนามบินต้นทาง จาก Z-A โดยใช้ decreasing = TRUE:

    # Sort descending with decreasing = TRUE
    flights[order(origin, decreasing = TRUE)]
    

    หรือโดยใช้ -:

    # Sort descending with -
    flights[order(-origin)]
    

    เราจะได้ผลลัพธ์แบบเดียวกัน:

             year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
            <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
         1:  2014     1     1        -8       -26      AA    LGA    PBI      157     1035     7
         2:  2014     1     1        -7        -6      AA    LGA    ORD      142      733     5
         3:  2014     1     1        -7         0      AA    LGA    ORD      143      733     6
         4:  2014     1     1        -8       -17      AA    LGA    ORD      139      733     6
         5:  2014     1     1        -2        15      AA    LGA    ORD      145      733     7
        ---                                                                                    
    253312:  2014    10    31        41        19      UA    EWR    SFO      344     2565    12
    253313:  2014    10    31       427       393      UA    EWR    ORD      100      719    21
    253314:  2014    10    31        10       -27      UA    EWR    LAX      326     2454    10
    253315:  2014    10    31        18       -14      UA    EWR    LAS      291     2227    16
    253316:  2014    10    31        -5       -14      UA    EWR    IAH      189     1400     8
    

    .

    แบบที่ #3 – Sort by multiple columns

    เช่น จัดเรียงตามชื่อสนามบินต้นทางและปลายทาง ตามลำดับ:

    # Sort by multiple columns
    flights[order(origin, dest)]
    

    ผลลัพธ์:

             year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
            <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
         1:  2014     1     2        -2       -25      EV    EWR    ALB       30      143     7
         2:  2014     1     3        88        79      EV    EWR    ALB       29      143    23
         3:  2014     1     4       220       211      EV    EWR    ALB       32      143    15
         4:  2014     1     4        35        19      EV    EWR    ALB       32      143     7
         5:  2014     1     5        47        42      EV    EWR    ALB       26      143     8
        ---                                                                                    
    253312:  2014    10    29         0         9      MQ    LGA    XNA      174     1147     6
    253313:  2014    10    29        -5       -16      MQ    LGA    XNA      162     1147    14
    253314:  2014    10    30        -4       -23      MQ    LGA    XNA      154     1147     6
    253315:  2014    10    30        -7       -11      MQ    LGA    XNA      157     1147    14
    253316:  2014    10    31        -5       -11      MQ    LGA    XNA      165     1147     6
    

    🧮 2nd Argument: j

    เราสามารถใช้ j เพื่อทำงานได้ 3 อย่าง ได้แก่:

    1. Select columns: เลือก columns ที่ต้องการ
    2. Compute: วิเคราะห์ข้อมูล
    3. Create columns: สร้าง columns ใหม่

    .

    1️⃣ Select Columns

    เราสามารถใช้ j เพื่อเลือก columns ได้ 3 แบบ:

    1. เลือก 1 column
    2. เลือกหลาย columns
    3. คัด columns ที่ไม่ต้องการออก

    .

    แบบที่ #1 – เลือก 1 column

    เช่น เลือก column สนามบินต้นทาง:

    # Select a column
    flights[, "origin"]
    

    ผลลัพธ์:

            origin
            <char>
         1:    JFK
         2:    JFK
         3:    JFK
         4:    LGA
         5:    JFK
        ---       
    253312:    LGA
    253313:    EWR
    253314:    LGA
    253315:    LGA
    253316:    LGA
    

    Note: เราสามารถใช้ตำแหน่ง (1, 2, 3, …) แทนชื่อ columns ("origin") ได้ แต่ไม่เป็นที่นิยม เพราะ columns อาจขยับตำแหน่งได้ และทำให้ผลลัพธ์เปลี่ยนไปได้

    .

    แบบที่ #2 – เลือกหลาย columns

    เราใช้ j เพื่อเลือกหลาย columns ได้ 3 วิธี:

    1. Vector
    2. List หรือ .()
    3. ..

    เช่น เลือก 3 columns คือ:

    • สนามบินต้นทาง
    • สนามบินปลายทาง
    • ระยะเวลาบิน

    โดยใช้ vector:

    # Select multiple columns with a vector
    flights[, c("origin", "dest", "air_time")]
    

    ผลลัพธ์:

            origin   dest air_time
            <char> <char>    <int>
         1:    JFK    LAX      359
         2:    JFK    LAX      363
         3:    JFK    LAX      351
         4:    LGA    PBI      157
         5:    JFK    LAX      350
        ---                       
    253312:    LGA    IAH      201
    253313:    EWR    IAH      189
    253314:    LGA    RDU       83
    253315:    LGA    DTW       75
    253316:    LGA    SDF      110
    

    โดยใช้ list:

    # Select multiple columns with a list
    flights[, list(origin, dest, air_time)]
    

    หรือใช้ .() ซึ่งเป็น shorthand สำหรับ list:

    # Select multiple columns using .()
    flights[, .(origin, dest, air_time)]
    

    ผลลัพธ์:

            origin   dest air_time
            <char> <char>    <int>
         1:    JFK    LAX      359
         2:    JFK    LAX      363
         3:    JFK    LAX      351
         4:    LGA    PBI      157
         5:    JFK    LAX      350
        ---                       
    253312:    LGA    IAH      201
    253313:    EWR    IAH      189
    253314:    LGA    RDU       83
    253315:    LGA    DTW       75
    253316:    LGA    SDF      110
    

    โดยใช้ .. ซึ่งเรามักใช้วิธีนี้เมื่อต้องการเลือก columns แบบ dynamic:

    # Select multiple columns using ..
    
    ## Create a vector of column names
    cols <- c("origin", "dest", "air_time")
    
    ## Select using ..
    flights[, ..cols]
    

    ผลลัพธ์:

            origin   dest air_time
            <char> <char>    <int>
         1:    JFK    LAX      359
         2:    JFK    LAX      363
         3:    JFK    LAX      351
         4:    LGA    PBI      157
         5:    JFK    LAX      350
        ---                       
    253312:    LGA    IAH      201
    253313:    EWR    IAH      189
    253314:    LGA    RDU       83
    253315:    LGA    DTW       75
    253316:    LGA    SDF      110
    

    Note: ความแตกต่างระหว่าง vector และ list หรือ .() และ .. คือ:

    • vector ให้ผลลัพธ์ที่เป็น vector
    • List หรือ .() และ .. ให้ผลลัพธ์เป็น data.table (data frame ของ data.table)

    .

    แบบที่ #3 – คัด columns ที่ไม่ต้องการออก

    เราสามารถคัด columns ที่ไม่ต้องการออกได้ 2 วิธี:

    1. ใช้ -
    2. ใช้ !

    เช่น เอาชื่อสายการบินออก โดยใช้ -:

    # Deselect a column using -
    flights[, -c("carrier")]
    

    หรือใช้ !:

    # Deselect a column using !
    flights[, !c("carrier")]
    

    ผลลัพธ์:

             year month   day dep_delay arr_delay origin   dest air_time distance  hour
            <int> <int> <int>     <int>     <int> <char> <char>    <int>    <int> <int>
         1:  2014     1     1        14        13    JFK    LAX      359     2475     9
         2:  2014     1     1        -3        13    JFK    LAX      363     2475    11
         3:  2014     1     1         2         9    JFK    LAX      351     2475    19
         4:  2014     1     1        -8       -26    LGA    PBI      157     1035     7
         5:  2014     1     1         2         1    JFK    LAX      350     2475    13
        ---                                                                            
    253312:  2014    10    31         1       -30    LGA    IAH      201     1416    14
    253313:  2014    10    31        -5       -14    EWR    IAH      189     1400     8
    253314:  2014    10    31        -8        16    LGA    RDU       83      431    11
    253315:  2014    10    31        -4        15    LGA    DTW       75      502    11
    253316:  2014    10    31        -5         1    LGA    SDF      110      659     8
    

    .

    2️⃣ Compute

    นอกจากการเลือก columns เรายังสามารถใช้ j เพื่อวิเคราะห์หรือข้อมูล (summarise, aggregate) ได้

    เช่น หาค่าเฉลี่ยของระยะเวลาบิน:

    # Calculate mean
    flights[, mean(air_time)]
    

    ผลลัพธ์:

    [1] 156.7228
    

    หรือ หาค่าเฉลี่ย และ standard deviation (SD) ของระยะเวลาบิน:

    # Calculate mean and SD
    flights[, .(avg_air_time = mean(air_time),
                sd_air_time = sd(air_time))]
    

    ผลลัพธ์:

       avg_air_time sd_air_time      n
              <num>       <num>  <int>
    1:     156.7228    96.12978 253316
    

    Note: เราสามารถวิเคราะห์ข้อมูลโดยไม่ตั้งชื่อให้กับผลลัพธ์ได้ (avg_air_time, sd_air_time, n) แต่การตั้งชื่อจะช่วยให้เราอ่าน output ได้ง่ายขึ้น

    .

    3️⃣ Create Columns

    สุดท้าย เราสามารถใช้ j สร้าง columns ใหม่ได้ร่วมกับ:

    1. := สำหรับสร้าง 1 column
    2. `:=` สำหรับสร้างหลาย columns

    เช่น สร้าง column ความเร็วในการบิน (ระยะทาง / เวลา) ด้วย :=:

    # Creating 1 new column
    flights[, speed := distance / (air_time / 60)]
    

    ผลลัพธ์:

        year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour    speed
       <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>    <num>
    1:  2014     1     1        14        13      AA    JFK    LAX      359     2475     9 413.6490
    2:  2014     1     1        -3        13      AA    JFK    LAX      363     2475    11 409.0909
    3:  2014     1     1         2         9      AA    JFK    LAX      351     2475    19 423.0769
    4:  2014     1     1        -8       -26      AA    LGA    PBI      157     1035     7 395.5414
    5:  2014     1     1         2         1      AA    JFK    LAX      350     2475    13 424.2857
    6:  2014     1     1         4         0      AA    EWR    LAX      339     2454    18 434.3363
    

    Note:

    • เราหาร air_time ด้วย 60 เพื่อแปลงหน่วยจากนาทีเป็นชั่วโมง และทำให้ผลลัพธ์ที่ได้เป็นหน่วย miles/hour
    • สังเกตว่า column ใหม่จะอยู่ท้ายสุดของ data.table

    หรือ สร้าง 2 columns พร้อมกัน เช่น:

    • ความเร็วในการบิน (ระยะทาง / เวลา)
    • ระยะเวลาที่ delay โดยรวม (delay ขาออก + delay ขาเข้า)

    ด้วย `:=`:

    # Creating multiple new column
    flights[, `:=`(speed = distance / (air_time / 60),
                   total_delay = dep_delay + arr_delay)]
    

    ผลลัพธ์:

        year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour    speed total_delay
       <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>    <num>       <int>
    1:  2014     1     1        14        13      AA    JFK    LAX      359     2475     9 413.6490          27
    2:  2014     1     1        -3        13      AA    JFK    LAX      363     2475    11 409.0909          10
    3:  2014     1     1         2         9      AA    JFK    LAX      351     2475    19 423.0769          11
    4:  2014     1     1        -8       -26      AA    LGA    PBI      157     1035     7 395.5414         -34
    5:  2014     1     1         2         1      AA    JFK    LAX      350     2475    13 424.2857           3
    6:  2014     1     1         4         0      AA    EWR    LAX      339     2454    18 434.3363           4
    

    🤝 3rd Argument: by

    เราใช้ by เพื่อจับกลุ่มข้อมูล ซึ่งมีประโยชน์มากเวลาที่เราต้องการวิเคราะห์ข้อมูลเป็น ๆ กลุ่ม

    เราสามารถใช้ by ได้ 2 แบบ:

    1. จับกลุ่มด้วย 1 column
    2. จับกลุ่มด้วยหลาย columns

    .

    แบบที่ #1 – จับกลุ่มด้วย 1 column

    เช่น หาค่าเฉลี่ยของ delay ขาออก ตามชื่อสนามบินต้นทาง:

    # Group by 1 column
    flights[, mean(dep_delay), by = origin]
    

    ผลลัพธ์:

       origin       V1
       <char>    <num>
    1:    JFK 11.44617
    2:    LGA 10.60500
    3:    EWR 15.21248
    

    .

    แบบที่ #2 – จับกลุ่มด้วยหลาย columns

    เราจับกลุ่มด้วยหลาย columns ได้ด้วย 2 วิธี คือ:

    1. Vector
    2. List หรือ .()

    เช่น หาค่าเฉลี่ยของ delay ขาออก โดยจับกลุ่มตามชื่อสนามบินต้นทางและปลายทาง ตามลำดับ

    วิธีที่ 1. ใช้ vector:

    # Group by with a vector
    flights[, mean(dep_delay), by = c("origin", "dest")]
    

    ผลลัพธ์:

         origin   dest        V1
         <char> <char>     <num>
      1:    JFK    LAX  8.359718
      2:    LGA    PBI 10.168617
      3:    EWR    LAX 15.882631
      4:    JFK    MIA 10.008364
      5:    JFK    SEA 10.858953
     ---                        
    217:    LGA    AVL -6.500000
    218:    LGA    GSP  6.000000
    219:    LGA    SBN  5.000000
    220:    EWR    SBN -1.500000
    221:    LGA    DAL -6.266667
    

    วิธีที่ 2. ใช้ list:

    # Group by with a list
    flights[, mean(dep_delay), by = list(origin, dest)]
    

    หรือใช้ .():

    # Group by with .()
    flights[, mean(dep_delay), by = .(origin, dest)]
    

    ผลลัพธ์:

         origin   dest        V1
         <char> <char>     <num>
      1:    JFK    LAX  8.359718
      2:    LGA    PBI 10.168617
      3:    EWR    LAX 15.882631
      4:    JFK    MIA 10.008364
      5:    JFK    SEA 10.858953
     ---                        
    217:    LGA    AVL -6.500000
    218:    LGA    GSP  6.000000
    219:    LGA    SBN  5.000000
    220:    EWR    SBN -1.500000
    221:    LGA    DAL -6.266667
    

    Note: เช่นเดียวกับการเลือก columns …

    • ถ้าเราใช้ vector เราจะได้ผลลัพธ์เป็น vector
    • ถ้าใช้ list หรือ .() เราจะได้ data.table

    🔗 Combining & Chaining

    เราสามารถปลอดล็อกพลังที่แท้จริงของ data.table ได้ด้วย 2 วิธี:

    1. Combining: ใช้ i, j, by ร่วมกัน เพื่อตอบโจทย์ที่ซับซ้อน
    2. Chaining: เชื่อมต่อ data.table เข้าด้วยกัน

    .

    1️⃣ Combining

    ยกตัวอย่างเช่น:

    • หาค่าเฉลี่ยของความเร็ว
    • เฉพาะเที่ยวบินที่มีระยะทางตั้งแต่ 500 miles ขึ้นไป
    • โดยจับกลุ่มตามชื่อสนามบินต้นทาง:
    # Combining
    flights[distance >= 500, 
            .(avg_speed = mean(distance / (air_time / 60))), 
            by = origin]
    

    อธิบาย code:

    • distance >= 500 เลือกเฉพาะข้อมูลที่มีระยะทางตั้งแต่ 500 miles ขึ้นไป
    • .(avg_speed = mean(distance / (air_time / 60))) หาค่าเฉลี่ยของความเร็ว
    • by = origin] จับกลุ่มข้อมูลด้วยสนามบินต้นทาง

    ผลลัพธ์:

       origin avg_speed
       <char>     <num>
    1:    JFK  436.6284
    2:    LGA  407.5462
    3:    EWR  417.1765
    

    .

    2️⃣ Chaining

    Chaining คือ การนำ code มาต่อกัน เพื่อส่ง output ต่อกันเป็นทอด ๆ:

    DT[...][...][...]

    เช่น ค้นหาสนามบินปลายทาง 5 อันดับแรกที่มีค่าเฉลี่ย delay ขาเข้ามากที่สุด ในเดือนสิงหาคม:

    # Chaining
    flights[month == 8,
            .(avg_arr_delay = mean(arr_delay)),
            by = dest][order(-avg_arr_delay)][1:5]
    

    อธิบาย code:

    • month == 8 เลือกข้อมูลจากเดือนสิงหาคม
    • .(avg_arr_delay = mean(arr_delay)) คำนวณค่าเฉลี่ย delay ขาเข้า
    • by = dest จับกลุ่มตามสนามบินปลายทาง
    • [order(-avg_arr_delay)] จัดลำดับตามค่าเฉลี่ย delay ขาเข้า แบบ descending
    • [1:5] เลือกเฉพาะ 5 rows แรกมาแสดง

    ผลลัพธ์:

         dest avg_arr_delay
       <char>         <num>
    1:    LIT      37.06452
    2:    DSM      22.85714
    3:    CAK      19.60976
    4:    TYS      19.44681
    5:    TVC      19.00000
    

    🍩 Special Symbols

    เพื่อช่วยให้เราทำงานได้ง่ายขึ้น data.table มี special symbols 3 ตัวที่เราสามารถเรียกใช้ในการทำงานได้:

    1. .N
    2. .SD
    3. .SDcols

    .

    1️⃣ .N

    .N เป็น special symbol ที่เก็บจำนวน rows ของ data.table เอาไว้ (เช่น 500)

    เรามักใช้งาน .N ใน 2 กรณีหลัก ๆ ได้แก่:

    1. เลือก rows
    2. นับจำนวนข้อมูล

    .

    กรณีที่ 1. เลือก rows

    เช่น เลือก row ที่ 500 จนถึง row สุดท้าย:

    # Select rows with .N
    flights[500:.N]
    

    ผลลัพธ์:

             year month   day dep_delay arr_delay carrier origin   dest air_time distance  hour
            <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
         1:  2014     1     1        81        86      WN    EWR    HOU      222     1411    17
         2:  2014     1     1        -3        -4      WN    EWR    MDW      128      711     7
         3:  2014     1     1         0        22      WN    EWR    MDW      144      711    12
         4:  2014     1     1        88       190      WN    EWR    MDW      130      711    21
         5:  2014     1     1        45        63      WN    EWR    MDW      141      711    16
        ---                                                                                    
    252813:  2014    10    31         1       -30      UA    LGA    IAH      201     1416    14
    252814:  2014    10    31        -5       -14      UA    EWR    IAH      189     1400     8
    252815:  2014    10    31        -8        16      MQ    LGA    RDU       83      431    11
    252816:  2014    10    31        -4        15      MQ    LGA    DTW       75      502    11
    252817:  2014    10    31        -5         1      MQ    LGA    SDF      110      659     8
    

    .

    กรณีที่ 2. นับจำนวนข้อมูล

    เช่น นับจำนวนข้อมูลการบินตามสนามบินต้นทางแต่ละแห่ง:

    # Compute with .N
    flights[, .N, by = origin]
    

    ผลลัพธ์:

       origin     N
       <char> <int>
    1:    JFK 81483
    2:    LGA 84433
    3:    EWR 87400
    

    .

    2️⃣ .SD

    .SD ย่อมาจาก “Subset of Data” ซึ่งหมายถึง ชุดข้อมูลย่อยที่เกิดจากการจับกลุ่มด้วย by

    เรามักใช้ .SD ในการคำนวณคู่กับ lapply() function เพื่อวิเคราะห์ข้อมูลตามกลุ่ม

    เช่น หาค่าสูงสุดของแต่ละ columns ในแต่ละเดือน:

    # Compute with .SD
    flights[,
            lapply(.SD, max, na.rm = TRUE),
            by = month]
    

    ผลลัพธ์:

        month  year   day dep_delay arr_delay carrier origin   dest air_time distance  hour
        <int> <int> <int>     <int>     <int>  <char> <char> <char>    <int>    <int> <int>
     1:     1  2014    31       973       996      WN    LGA    XNA      688     4983    24
     2:     2  2014    28      1014      1007      WN    LGA    XNA      685     4983    24
     3:     3  2014    31       920       925      WN    LGA    XNA      706     4983    24
     4:     4  2014    30      1241      1223      WN    LGA    XNA      664     4983    24
     5:     5  2014    31       889       879      WN    LGA    XNA      650     4983    24
     6:     6  2014    30      1071      1073      WN    LGA    XNA      640     4983    24
     7:     7  2014    31      1087      1090      WN    LGA    XNA      638     4983    24
     8:     8  2014    31       978       964      WN    LGA    XNA      635     4983    24
     9:     9  2014    30      1056      1115      WN    LGA    XNA      635     4983    23
    10:    10  2014    31      1498      1494      WN    LGA    XNA      662     4983    24
    

    .

    3️⃣ .SDcols

    .SDcols เป็น special symbol ที่เก็บชื่อ columns ของ .SD เอาไว้

    เรามักใช้ .SDcols คู่กับ .SD และ lapply() เพื่อวิเคราะห์เฉพาะ columns ที่ต้องการ

    เช่น หาเวลา delay สูงสุดของขาเข้าและขาออกในแต่ละเดือน:

    # Compute with .SDcols
    flights[,
            lapply(.SD, max, na.rm = TRUE),
            by = month,
            .SDcols = c("arr_delay", "dep_delay")]
    

    ผลลัพธ์:

        month arr_delay dep_delay
        <int>     <int>     <int>
     1:     1       996       973
     2:     2      1007      1014
     3:     3       925       920
     4:     4      1223      1241
     5:     5       879       889
     6:     6      1073      1071
     7:     7      1090      1087
     8:     8       964       978
     9:     9      1115      1056
    10:    10      1494      1498
    

    😎 Conclusion

    ในบทความนี้ เราได้ไปดูวิธีใช้ data.table เพื่อทำทำงานกับข้อมูลขนาดใหญ่กัน

    เราได้เห็นว่า data.table มีหลักการเขียนดังนี้:

    DT[i, j, by]

    และแต่ละ argument มีการใช้งานดังนี้:

    .

    Argument i:

    Use CaseExample
    Select rowsflights[1:5]
    Filterflights[distance >= 500]
    Sortflights[order(origin)]

    .

    Argument j:

    Use CaseExample
    Select columnsflights[, .(origin, dest)]
    Computeflights[, mean(air_time)]
    Create columnsflights[, speed := distance / (air_time / 60)]

    .

    Argument by:

    Use CaseExample
    Group dataflights[by = origin]

    .

    Special symbols:

    SymbolMeaning
    .Nจำนวน rows
    .SDSubset of Data
    .SDcolscolumns ใน Subset of Data

    .

    เราสามารถใช้ทุก arguments ร่วมกัน (combining) หรือเชื่อมต่อ data.table (chaining) เพื่อตอบโจทย์ที่ซับซ้อนได้


    🎒 Learn More About data.table

    .

    😺 GitHub

    ดู code ตัวอย่างทั้งหมดในบทความนี้ได้ที่ GitHub

    .

    📚 อ่านเพิ่มเติมเกี่ยวกับ data.table

    .

    📑 Cheat Sheets ในการใช้งาน data.table


    📃 References


    ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    📕 ขอฝากหนังสือเล่มแรกในชีวิตด้วยนะครับ 😆

    🙋 ใครที่กำลังเรียนจิตวิทยาหรือทำงานสายจิตวิทยา และเบื่อที่ต้องใช้ software ราคาแพงอย่าง SPSS และ Excel เพื่อทำข้อมูล

    💪 ผมขอแนะนำ R Book for Psychologists หนังสือสอนใช้ภาษา R เพื่อการวิเคราะห์ข้อมูลทางจิตวิทยา ที่เขียนมาเพื่อนักจิตวิทยาที่ไม่เคยมีประสบการณ์เขียน code มาก่อน

    ในหนังสือ เราจะปูพื้นฐานภาษา R และพาไปดูวิธีวิเคราะห์สถิติที่ใช้บ่อยกัน เช่น:

    • Correlation
    • t-tests
    • ANOVA
    • Reliability
    • Factor analysis

    🚀 เมื่ออ่านและทำตามตัวอย่างใน R Book for Psychologists ทุกคนจะไม่ต้องพึง SPSS และ Excel ในการทำงานอีกต่อไป และสามารถวิเคราะห์ข้อมูลด้วยตัวเองได้ด้วยความมั่นใจ

    แล้วทุกคนจะแปลกใจว่า ทำไมภาษา R ง่ายขนาดนี้ 🙂‍↕️

    👉 สนใจดูรายละเอียดหนังสือได้ที่ meb:

  • R Control Flow: วิธีเขียน if, for, while ในภาษา R เพื่อการทำงานที่ง่ายขึ้น พร้อมตัวอย่าง

    R Control Flow: วิธีเขียน if, for, while ในภาษา R เพื่อการทำงานที่ง่ายขึ้น พร้อมตัวอย่าง

    ในการเขียน code เรามักจะเจอกับงานที่เราต้องทำซ้ำ ๆ เช่น เปลี่ยนตัวเลขในช่วงที่กำหนด (เช่น 80 ถึง 100) ให้เป็นเกรด (เช่น A)

    แทนที่เราจะเขียน code ใหม่ทุกครั้งที่เราเจอตัวเลข (เช่น 89, 82, 91) เราสามารถใช้ control flow เข้ามาช่วย automate งาน ลดเวลาและภาระงานของเราลงไปได้

    .

    ในบทความนี้ เราจะมาดูวิธีเขียน control flow ในภาษา R กัน:

    • If-else:
      • if
      • else
      • else if
    • Loops:
      • for
      • while
    • Loop control:
      • next
      • break

    ถ้าพร้อมแล้ว มาเริ่มกันเลย


    1. 🕹️ If-Else
      1. 1️⃣ if
      2. 2️⃣ else
      3. 3️⃣ else if
    2. 🔁 Loops
      1. 1️⃣ for
      2. 2️⃣ while
    3. 🚸 Loop Control
      1. 1️⃣ next
      2. 2️⃣ break
    4. 💪 Summary
    5. 🗒️ Practice Control Flow
    6. 😺 GitHub
    7. 📃 References
    8. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    🕹️ If-Else

    ในการเขียน if-else เรามี 3 syntax ที่ต้องทำความเข้าใจ:

    1. if
    2. else
    3. else if

    .

    1️⃣ if

    เราใช้ if เพื่อกำหนดเงื่อนไขในการทำงาน

    เช่น ถ้าคะแนนมากกว่า 60 ให้ผ่าน:

    if (score >= 60) {
    	print("Pass")
    }
    

    ถ้าไม่ตรงกับเงื่อนไข R จะรัน code บรรทัดถัดไป

    .

    2️⃣ else

    เราใช้ else เพื่อกำหนด action ที่ต้องทำเมื่อข้อมูลไม่เข้าเงื่อนไข

    เช่น ถ้าน้อยกว่า 60 ให้ไม่ผ่าน:

    if (score >= 60) {
    	print("Pass")
    } else {
    	print("Fail")
    }
    

    ในครั้งนี้ R จะแสดงคำว่า “Pass” หรือ “Fail” ก่อนจะรัน code บรรทัดถัดไป

    .

    3️⃣ else if

    ถ้าเรามีมากกว่า 2 เงื่อนไข ให้ใช้ else if เพื่อกำหนดเงื่อนไขเพิ่มเติม

    เช่น ตัดเกรดตามช่วงคะแนน:

    if (score >= 90) {
    	print("A")
    } else if (score >= 80) {
    	print("B")
    } else if (score >= 70) {
    	print("C")
    } else if (score >= 60) {
    	print("D")
    } else {
    	print("F")
    }
    

    ใน code นี้ R จะรันแต่ละบรรทัด และถ้าข้อมูลที่มีตรงกับเงื่อนไข ก็จะทำตาม action ในบรรทัดนั้น

    เช่น เรากำหนดให้:

    score <- 71
    

    R จะรัน else if จนถึงบรรทัดที่ 5 แล้วทำ action ที่อยู่ในบรรทัด 6:

    if, else if, else

    🔁 Loops

    Loops ใช้ในการทำ task ซ้ำเรื่อย ๆ ตามเงื่อนไขที่กำหนด

    เราสามารถเขียน loop ได้ 2 แบบ คือ:

    1. for
    2. while

    .

    1️⃣ for

    for ใช้สำหรับทำงานซ้ำ ๆ ที่เรารู้ว่าจะต้องทำกี่ครั้ง

    เช่น เรามีรายชื่อเพื่อนที่เราอยากจะทักทาย:

    friends <- c("John",
                 "Sarah", 
                 "Emma",
                 "Mike")
    

    เราสามารถใช้ for loop ช่วยได้แบบนี้:

    for (friend in friends) {
      print(paste("Hello,", friend))
    }
    

    ผลลัพธ์:

    for loop

    .

    2️⃣ while

    เราใช้ while เมื่อต้องทำงานซ้ำ ๆ ที่เราไม่รู้ว่าจะต้องทำกี่ครั้ง

    โดย while จะทำงานไปเรื่อย ๆ จนกว่าเงื่อนไขที่กำหนดจะไม่เป็นจริง

    เช่น ทอยเต๋าเรื่อย ๆ จนกว่าจะได้เลข 6:

    set.seed(42)
    
    roll <- sample(1:6, 1)
    
    while (roll != 6) {
      print(paste("Rolled:", roll, "Not yet..."))
      roll <- sample(1:6, 1)
    }
    
    print("You rolled a 6! Congratulations!")
    

    อธิบาย code:

    CodeExplain
    set.seed(42)ทำให้ code ให้ผลลัพธ์เหมือนกันทุกครั้ง
    sample(1:6, 1)สุ่ม 1 เลข ระหว่าง 1 ถึง 6
    while (roll != 6) {...}จนกว่า roll จะเท่ากับ 6 ให้ทำ action ใน {...}
    print("You rolled a 6! Congratulations!")ถ้าหลุดจาก while loop แล้ว ให้ print “You rolled a 6! Congratulations!”

    ถ้ารัน code แล้ว เราจะได้ผลลัพธ์แบบนี้:

    while loop

    จะเห็นว่า while loop หยุดเมื่อ roll != 6 ไม่เป็นจริง (เมื่อ roll = 6)


    🚸 Loop Control

    ในการเขียน for และ while loops เรามี 2 statements ที่ช่วยกำกับ loops ได้ คือ:

    1. next
    2. break

    .

    1️⃣ next

    next ใช้เพื่อข้ามข้อมูลที่เราไม่ต้องการให้เกิด action

    เช่น เรามี list ของสี:

    colours <- c("🟢", "🔴", "🔵", "🔴", "🟠", "🟢")
    

    ซึ่งเราต้องการ print เฉพาะสีโทนเย็น (skip สีโทนร้อน เช่น 🔴, 🟠) เราสามารถใช้ next คู่กับ if และ for ได้แบบนี้:

    for (colour in colours) {
      if (colour == "🔴" | colour == "🟠") next
      print(colour)  
    }
    

    ผลลัพธ์:

    next

    จะเห็นได้ว่า code ของเราข้ามข้อมูลที่เป็นสีโทนร้อน และ print เฉพาะสีโทนเย็นออกมา

    .

    2️⃣ break

    break ทำหน้าที่คล้าย next

    แต่แทนที่จะข้ามข้อมูลไป break จะหยุดการทำงานของ loop และปล่อยให้ R รัน code บรรทัดหลังจาก loop ได้

    เช่น เรามี while loop ที่นับเลขตั้งแต่ 10 ถึง 0:

    time <- 10  # Start countdown
    
    while (time > 0) {
      print(paste("Counting down:", time))
      time <- time - 1
    }
    

    ถ้าเราไม่ใส่ break, while loop ของเราจะนับเลขถึง 0:

    while without break

    .

    แต่ถ้าเราใส่ break เข้าไป while loop จะหยุดนับ ณ ตัวเลขที่เรากำหนด:

    time <- 10  # Start countdown
    
    while (time > 0) {
      if (time == 4) {
        print("Countdown stopped.")
        break  # Stop the loop when time reaches 4
      }
      print(paste("Counting down:", time))
      time <- time - 1
    }
    

    ผลลัพธ์:

    while with break

    จะเห็นได้ว่า break ทำให้ while loop หยุดทำงาน เมื่อนับถึง 4


    💪 Summary

    ในบทความนี้ เราเรียนรู้วิธีเขียน control flow ใน R กัน:

    If-else:

    StatementDescription
    ifกำหนด 1 เงื่อนไข
    elseทำ action เมื่ออยู่นอกเงื่อนไข
    else ifเพิ่มเงื่อนไข

    Loops:

    StatementDescription
    forrepeat task เมื่อรู้ว่า action ที่ต้องทำจะเกิดขึ้นกี่ครั้ง
    whilerepeat task เมื่อไม่รู้ว่า action ที่ต้องทำจะเกิดขึ้นกี่ครั้ง

    Loop control:

    StatementDescription
    nextSkip ข้อมูลใน loop
    breakหยุด loop

    🗒️ Practice Control Flow

    แม้ว่าตัวอย่างในบทความนี้จะเป็นตัวอย่างง่าย ๆ แต่ control flow เป็นการเขียน code ที่มีประโยชน์มาก และสามารถใช้แก้ปัญหาทั้งเล็กและใหญ่ในโลกจริงได้ เช่น:

    • ส่ง update ข้อมูล PM2.5 รายวัน
    • เช็ก username และ password เพื่อยืนยันการเข้าสู่ระบบ
    • ทำระบบสั่งอาหารและจ่ายเงินออนไลน์
    • สร้างเกมเป่ายิ้งฉุบ
    • สร้างระบบกดเงิน ATM

    และอีกมากมาย

    .

    สำหรับคนที่สนใจสามารถลองเขียน control flow เพื่อแก้ปัญหาเหล่านี้ได้

    .

    ติดตั้ง R และ RStudio เพื่อใช้งาน R:


    😺 GitHub

    ดูตัวอย่าง code ในบทความนี้ได้ที่ GitHub


    📃 References


    ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    📕 ขอฝากหนังสือเล่มแรกในชีวิตด้วยนะครับ 😆

    🙋 ใครที่กำลังเรียนจิตวิทยาหรือทำงานสายจิตวิทยา และเบื่อที่ต้องใช้ software ราคาแพงอย่าง SPSS และ Excel เพื่อทำข้อมูล

    💪 ผมขอแนะนำ R Book for Psychologists หนังสือสอนใช้ภาษา R เพื่อการวิเคราะห์ข้อมูลทางจิตวิทยา ที่เขียนมาเพื่อนักจิตวิทยาที่ไม่เคยมีประสบการณ์เขียน code มาก่อน

    ในหนังสือ เราจะปูพื้นฐานภาษา R และพาไปดูวิธีวิเคราะห์สถิติที่ใช้บ่อยกัน เช่น:

    • Correlation
    • t-tests
    • ANOVA
    • Reliability
    • Factor analysis

    🚀 เมื่ออ่านและทำตามตัวอย่างใน R Book for Psychologists ทุกคนจะไม่ต้องพึง SPSS และ Excel ในการทำงานอีกต่อไป และสามารถวิเคราะห์ข้อมูลด้วยตัวเองได้ด้วยความมั่นใจ

    แล้วทุกคนจะแปลกใจว่า ทำไมภาษา R ง่ายขนาดนี้ 🙂‍↕️

    👉 สนใจดูรายละเอียดหนังสือได้ที่ meb:

  • R Foundation: ทำความรู้จักกับภาษา R สำหรับผู้เริ่มต้น – ภาษา R คืออะไร, ต่างกับ Python ยังไง, และเขียนยังไง?

    R Foundation: ทำความรู้จักกับภาษา R สำหรับผู้เริ่มต้น – ภาษา R คืออะไร, ต่างกับ Python ยังไง, และเขียนยังไง?

    ในบทความนี้ เราจะมาทำความรู้จักภาษา R กัน:

    • ภาษา R คืออะไร?
    • R แตกต่างกับ Python ยังไง?
    • พื้นฐานการเขียนภาษา R

    ถ้าพร้อมแล้วมาเริ่มกันเลย


    1. 😆 ภาษา R คืออะไร?
    2. 🐍 R vs Python: แตกต่างกันยังไง?
    3. 🌏 Objects & Functions: โลกทั้งใบของ R
    4. 🧘 Objects: Existing in R
      1. 📦 (1) Variables: การประกาศตัวแปรใน R
      2. 🍱 (2) Data Types & Classes: ประเภทข้อมูลใน R
      3. 🏠 (3) Data Structures: โครงสร้างข้อมูลใน R
    5. 👟 Functions: Happening in R
      1. 🧮 (1) Operators: เครื่องหมายใน R
      2. 🔨 (2) Functions: Action ใน R
    6. 💪 Summary
    7. ⏭️ Learn More About R
      1. 🧑‍💻 GitHub
      2. 🔨 Free Tool
      3. 📗 Free e-Books
      4. 🏫 Free Courses
    8. 📄 References
    9. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    😆 ภาษา R คืออะไร?

    R เป็นภาษาคอมพิวเตอร์ที่ถูกพัฒนาขึ้นในช่วง ค.ศ. 1990 โดยนักสถิติ 2 ท่านจาก University of Auckland ในนิวซีแลนด์:

    • Ross Ihaka
    • Robert Gentleman

    โดยทั้งคู่พัฒนา R เพื่อทำงานกับข้อมูลในห้องแล็บโดยเฉพาะ

    และด้วยเหตุที่ R ถูกออกแบบมาเพื่อทำงานกับข้อมูล จึงได้ชื่อว่าเป็น “statistical programming language”

    Note: ตัวอักษรแรกของนักพัฒนาเป็นที่มาของชื่อภาษา

    “Logo for R” by The R Foundation (from https://www.r-project.org/logo/ under the CC-BY-SA 4.0)

    .

    เพราะ R เป็นภาษาสำหรับ data จึงเป็นที่นิยมในสายอาชีพ data อย่าง:

    • Data analyst
    • Data scientist
    • Business intelligence analyst
    • Statistician
    • Researcher

    .

    ในปัจจุบัน (Jan 2025) R ได้รับความนิยมเป็นอันดับ 18 ของโลก (อ้างอิง TIOBE index):

    TIOBE index

    นอกจากเป็นภาษา data แล้ว R ยังได้รับความนิยม เพราะ:

    • เป็นภาษา open source
    • ผู้ใช้งานสามารถสร้าง package (library) ในการวิเคราะห์ข้อมูลเองได้
    • ผู้ใช้สามารถใช้ package ที่คนอื่นเขียนไว้แล้ว มาวิเคราะห์ข้อมูลได้ (ในปัจจุบัย R มี package ให้เลือกใช้งานมากกว่า 17,000 packages)
    • ใช้งานได้กับหลากหลาย OS เช่น Windows, MacOS, และ Linux

    🐍 R vs Python: แตกต่างกันยังไง?

    ทั้ง R และ Python ต่างได้เป็นที่นิยมในสายงาน data science และมีลักษณะที่คล้ายกัน คือ:

    • เป็นภาษา open source
    • มี community ผู้ใช้งานขนาดใหญ่
    • มี packages ให้เลือกใช้จำนวนมาก

    แต่ R และ Python จุดที่แตกต่างกัน คือ:

    RPython
    เหมาะกับการทำงาน data โดยเฉพาะการวิเคราะห์สถิติเชิงลึกเป็นภาษาสำหรับงานทั่วไป (general-purpose) รองรับการใช้งานหลายประเภทกว่า R

    ดังนั้น แม้ว่า R อาจจะสามารถทำงานนอกเหนือจากงาน data ได้ (เช่น web scrapping) แต่อาจจะไม่ดีเท่ากับ Python ที่ถูกออกแบบมาให้ใช้งานทั่วไป

    .

    Note:

    สำหรับคนที่สนใจสายงาน data ควรเลือกศึกษาทั้ง 2 ภาษา

    แต่การจะหยิบมาใช้งาน ขึ้นอยู่กับงานตรงหน้า:

    RPython
    งานวิจัยและการวิเคราะห์ข้อมูลเชิงลึก เช่น สร้างโมเดลทางสถิติ รวมทั้งการสร้างกราฟจากข้อมูลอย่างง่ายงานที่ต้องมีความยืดหยุ่น เช่น machine learning และ AI

    หรืองานที่ต้อง integrate กับเครื่องมืออื่น ๆ เช่น web scrapping และ software development

    🌏 Objects & Functions: โลกทั้งใบของ R

    หลังจากทำความรู้จักความรู้จักกับ R เบื้องต้นแล้ว เรามาดูหลักการทำงานของ R กัน

    ในการทำงานกับ R เราต้องเข้าใจก่อนว่า ทุกสิ่งที่อยู่ใน R ประกอบด้วย 2 อย่าง ได้แก่:

    ObjectFunction
    สิ่งที่เก็บใน Rสิ่งที่เกิดขึ้นใน R

    นั่นคือ:

    • ทุกสิ่งที่เราสร้างขึ้นใน R จะถูกเก็บอยู่ใน objects (เช่น ตัวแปร, ข้อมูล)
    • Functions เป็นสิ่งที่เรากระทำกับ objects (เช่น การคำนวณ การสร้างกราฟ)

    เมื่อเราเข้าใจแล้ว เราสามารถทำความเข้าใจ concepts อื่น ๆ ของ โดยการต่อยอดจาก 2 องค์ประกอบนี้


    🧘 Objects: Existing in R

    ในส่วน objects เรามี 3 สิ่งที่ต้องความเข้าใจ เพื่อทำงานกับ R:

    1. Variables
    2. Data types and classes
    3. Data structures

    .

    📦 (1) Variables: การประกาศตัวแปรใน R

    Variable หรือตัวแปร เป็นเหมือนกล่องเก็บของที่เก็บข้อมูลไว้ให้เรา

    เราสามารถสร้างตัวแปรด้วยการใช้ <- เช่น:

    x <- 10
    

    อย่างในตัวอย่าง เป็นการสร้างตัวแปร x ที่เก็บค่าตัวเลข 10 เอาไว้

    Note: เราสามารถใช้ = แทน <- ได้ แต่ไม่เป็นที่นิยมกัน

    .

    🍱 (2) Data Types & Classes: ประเภทข้อมูลใน R

    ตัวแปรใน R สามารถเก็บข้อมูลได้หลายประเภท (เช่น ตัวเลข ข้อความ)

    เราต้องทำความเข้าใจประเภทของข้อมูล เพราะเป็นตัวกำหนด functions ที่เราสามารถใช้ทำงานกับ variable นั้นได้

    ยกตัวอย่างเช่น x เก็บตัวแปรประเภทตัวเลข เราจะไม่สามารถใช้ functions ที่ทำงานกับตัวอักษรได้

    .

    ทั้งนี้ ประเภทข้อมูลใน R มีอยู่ 5 ประเภทที่มักใช้บ่อย ได้แก่:

    No.Data TypeExample
    1Numeric100
    2Character"One hundred"
    3LogicalTRUE, FALSE
    4Date2025-01-15
    5Factor"male", "female", "other"

    .

    ตัวอย่าง 👇

    Numeric:

    age <- 10
    

    Character:

    name <- "Ben Tennyson"
    

    Logical:

    is_hero <- TRUE
    

    Date:

    date_of_birth <- as.Date("1995-12-27")
    

    Factor:

    gender <- as.factor("Male")
    

    .

    Note: เราสามารถเช็กประเภทข้อมูลของตัวแปร ได้ด้วย class() เช่น:

    class(age)
    

    ผลลัพธ์:

    class()

    .

    🏠 (3) Data Structures: โครงสร้างข้อมูลใน R

    Data structure เป็นการนำข้อมูลมาจัดเรียงเป็นโครงสร้างที่ใหญ่ขึ้น

    Data structures เป็นเหมือนอิฐที่ประกอบกันเป็นบ้านหรือตึกใน R

    .

    โครงสร้างข้อมูลใน R มีอยู่ 5 ประเภท ซึ่งแบ่งได้เป็น 2 กลุ่มตามมิติในการเก็บข้อมูล ดังนี้:

    .

    กลุ่มที่ 1: เก็บข้อมูลได้ 1 ประเภทเท่านั้น

    No.Data Structureการเก็บข้อมูล
    1Vector1 มิติ
    2Matrix2 มิติ
    3Arrayn มิติ

    .

    ตัวอย่าง 👇

    Vector:

    v <- c(1, 3, 5, 7, 9)
    

    ผลลัพธ์:

    Vector

    Matrix:

    m <- matrix(1:9, ncol = 3)
    

    ผลลัพธ์:

    Matrix

    Array:

    เช่น array แบบ 3 มิติ:

    • 4 rows
    • 3 columns
    • 2 ชั้น
    a <- array(1:24, dim = c(4, 3, 2))
    

    ผลลัพธ์:

    Array

    .

    กลุ่มที่ 2: เก็บข้อมูลได้มากกว่า 1 ประเภท

    No.Data Structureการเก็บข้อมูล
    1List1 มิติ
    2Data frame2 มิติ

    .

    ตัวอย่าง 👇

    List:

    เพราะ list สามารถเก็บข้อมูลได้หลายประเภท เราสามารถใส่อะไรลงใน list ก็ได้ (แม้แต่ data structure อื่น ๆ):

    grocery_list = list("apple",
                        "milk",
                        TRUE,
                        250,
                        c(1, 3, 5, 7, 9),
                        list("Walmart", "Target"))
    

    ผลลัพธ์:

    List

    Data frame:

    สำหรับ data frame เราสามารถสร้างได้จากเชื่อม vectors เข้าด้วยกัน:

    groceries <- data.frame(
      Item = c("Apples", "Carrots", "Milk"),
      Category = c("Fruit", "Vegetable", "Dairy"),
      Quantity = c(5, 2, 1),
      Price = c(1.50, 0.75, 2.50)
    )
    

    ผลลัพธ์:

    Data frame

    .

    Note: สำหรับใครที่นึกภาพโครงสร้างข้อมูลไม่ออก สามารถดู Figure 5.6 ในหนังสือ Hands-On R Programming เพื่อช่วยไขข้อสงสัยได้


    👟 Functions: Happening in R

    สำหรับ functions เรามี 2 สิ่งที่ต้องทำความเข้าใจ ได้แก่:

    1. Operators
    2. Functions

    .

    🧮 (1) Operators: เครื่องหมายใน R

    Operators เป็นเครื่องหมาย เพื่อบอก R ว่าเราต้องการทำงานหรือการคำนวณอะไร

    .

    Operators แบ่งออกเป็น 4 ประเภท ได้แก่:

    No.OperatorForSymbols
    1Assignmentสร้าง variable<-
    =
    2Arithmeticคิดเลข+
    -
    *
    /
    3Logicalคิดตรรกะ&
    |
    !
    4Relationalเปรียบเทียบค่า==
    !=
    >
    <
    >=
    <=

    .

    ตัวอย่าง 👇

    Assignment

    เช่น สร้างตัวแปรเก็บชื่อ “John”:

    my_name <- "John"
    

    Arithmetic

    เช่น คิดเลข 3 + 4:

    3 + 4
    

    Logical

    เช่น not TRUE:

    !TRUE
    

    Relational

    เช่น เช็กว่า 15 มากกว่า 11 ไหม:

    15 > 11
    

    .

    🔨 (2) Functions: Action ใน R

    Functions คือ code ที่เราสามารถนำกลับมาใช้ใหม่ได้ (reusable)

    .

    Functions แบ่งออกเป็น 2 ประเภท ได้แก่:

    No.FunctionDescriptionExample
    1Built-inFunctions ที่มาพร้อม R หรือ packages ที่เราโหลดมาใช้งานprint()
    sum()
    str()
    2User-definedFunctions ที่เราสร้างเองสร้าง function ชื่อ hello() เพื่อทักทาย user

    .

    Note:

    สำหรับ user-defined functions เราสามารถสร้างได้โดยใช้ function() เช่น:

    greeting <- function(name) {
      print(paste("Hello", name))
    }
    

    ถ้าเราเรียกใช้งาน greeting() โดยใส่ "John" ใน ():

    greeting("John")
    

    เราจะได้ผลลัพธ์แบบนี้:

    User-defined function

    💪 Summary

    ในบทความนี้ เราได้ทำความรู้กับภาษา R กัน:

    • R เป็นภาษาสำหรับงาน data
    • ทั้ง R และ Python ใช้กับงาน data ได้
      • R เหมาะกับการวิเคราะห์เชิงลึก
      • Python เหมาะกับงานทั่วไป
      • คนที่สนใจงานสาย data ควรเรียนทั้ง 2 ภาษา
    • ทุกอย่างใน R แบ่งเป็น objects และ functions
    • Objects: สิ่งที่เก็บใน R
      • Variables: เก็บข้อมูล
      • Data types and classes: กำหนด functions
      • Data structures: ประกอบร่างข้อมูล
    • Functions: สิ่งที่เกิดขึ้นใน R
      • Operators: เครื่องหมายในการทำงาน
      • Functions: code ที่นำกลับมาใช้ใหม่ได้

    ⏭️ Learn More About R

    .

    🧑‍💻 GitHub

    สำหรับผู้ที่สนใจ สามารถดู code ตัวอย่างในบทความนี้ได้ที่ GitHub

    .

    🔨 Free Tool

    เริ่มทดลองเขียน R ด้วยตัวเอง ผ่าน RStudio

    ดาวน์โหลด R

    RStudio desktop

    Note: ใช้งานฟรีทั้งแบบ desktop และ online

    .

    📗 Free e-Books

    ใครที่สนใจเรียนรู้เกี่ยวกับ R เพิ่มเติม สามารถอ่านหนังสือ e-book เหล่านี้ได้ฟรี:

    .

    🏫 Free Courses

    สำหรับคนที่สนใจเรียนการเขียน R สามารถศึกษาคอร์สเรียนเหล่านี้ได้:


    📄 References


    ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    📕 ขอฝากหนังสือเล่มแรกในชีวิตด้วยนะครับ 😆

    🙋 ใครที่กำลังเรียนจิตวิทยาหรือทำงานสายจิตวิทยา และเบื่อที่ต้องใช้ software ราคาแพงอย่าง SPSS และ Excel เพื่อทำข้อมูล

    💪 ผมขอแนะนำ R Book for Psychologists หนังสือสอนใช้ภาษา R เพื่อการวิเคราะห์ข้อมูลทางจิตวิทยา ที่เขียนมาเพื่อนักจิตวิทยาที่ไม่เคยมีประสบการณ์เขียน code มาก่อน

    ในหนังสือ เราจะปูพื้นฐานภาษา R และพาไปดูวิธีวิเคราะห์สถิติที่ใช้บ่อยกัน เช่น:

    • Correlation
    • t-tests
    • ANOVA
    • Reliability
    • Factor analysis

    🚀 เมื่ออ่านและทำตามตัวอย่างใน R Book for Psychologists ทุกคนจะไม่ต้องพึง SPSS และ Excel ในการทำงานอีกต่อไป และสามารถวิเคราะห์ข้อมูลด้วยตัวเองได้ด้วยความมั่นใจ

    แล้วทุกคนจะแปลกใจว่า ทำไมภาษา R ง่ายขนาดนี้ 🙂‍↕️

    👉 สนใจดูรายละเอียดหนังสือได้ที่ meb:

  • เล่นกับข้อมูลง่าย ๆ ด้วย 5 functions จาก dplyr: วิธีใช้งาน dplyr เบื้องต้น พร้อมตัวอย่างการทำงานกับข้อมูล HR

    เล่นกับข้อมูลง่าย ๆ ด้วย 5 functions จาก dplyr: วิธีใช้งาน dplyr เบื้องต้น พร้อมตัวอย่างการทำงานกับข้อมูล HR

    1. 💻 ภาษา R
    2. 🔢 dplyr: Library สำหรับหมุนข้อมูล
    3. 🧑‍💼 ตัวอย่างข้อมูล HR
    4. ✍️ Pattern การเขียน Function
    5. 1️⃣ Function #1: select()
    6. 2️⃣ Function #2: filter()
    7. 3️⃣ Function #3: arrange()
    8. 4️⃣ Function #4: summarise()
    9. 5️⃣ Function #5: mutate()
    10. 🫂 Put Everything Together: Pipe Operator
    11. 🔥 สรุป 5 Functions จาก dplyr
    12. 💪 Try It Yourself
    13. 📚 อ่านเพิ่มเติมเกี่ยวกับ dplyr
    14. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    💻 ภาษา R

    R เป็นภาษาคอมพิวเตอร์ที่ออกแบบมาเพื่อทำงานกับ data เหมาะกับสายงานที่ต้องทำงานกับ data เช่น

    • Researcher ที่ต้องการวิเคราะห์ลักษณะกลุ่มตัวอย่าง เช่น จำนวนตัวอย่างแบ่งตามเพศ หรือช่วงอายุ
    • Data analyst ที่ต้องการหา insight จากข้อมูลขององค์กร เช่น วิเคราะห์แนวโน้มทางธุรกิจ
    • Sale ที่ต้องการวิเคราะห์ข้อมูลการขาย เช่น จำนวนลูกค้า ยอดขาย และกำไร
    • หรือแม้แต่ HR ที่ต้องการทำข้อมูลพนักงาน เช่น วิเคราะห์ performance, engagement, และ job satisfaction

    🔢 dplyr: Library สำหรับหมุนข้อมูล

    R มี built-in functions และ libraries หลากหลายที่รองรับการทำงานกับ data ในรูปแบบต่าง ๆ ซึ่งหนึ่งใน libraries ที่นิยมใช้กัน ได้แก่ dplyr

    dplyr เป็น library ที่ออกแบบมาเพื่อ data transformation หรือการแปลงข้อมูล ช่วยให้การทำงานกับ data ง่ายขึ้น เมื่อเทียบกับ built-in functions

    Use case ของ dplyr เช่น:

    • สำรวจข้อมูล (data exploration)
    • ทำความสะอาดข้อมูล (data cleaning)
    • วิเคราะห์ข้อมูล (data analysis)

    .

    ในบทความนี้ เราจะไปทำความรู้จักกับ 5 functions พื้นฐานของ dplyr ที่ใช้ทำงานกับข้อมูลกัน ซึ่งได้แก่:

    1. select()
    2. filter()
    3. arrange()
    4. summarise() หรือ summarize() (เขียนได้ทั้งสองแบบ)
    5. mutate()

    🧑‍💼 ตัวอย่างข้อมูล HR

    ในบทความนี้ เราจะใช้ชุดข้อมูลจำลอง hr_data เพื่อช่วยอธิบายการใช้งาน 5 functions ของ dplyr

    hr_data ช่วยจำลองสถานการณ์ของ HR ที่ต้องวิเคราะห์ข้อมูลพนักงาน เพื่อหาวิธีแก้ปัญหาพนักงานลาออก (attrition)

    โดย hr_data ประกอบด้วย 8 ตัวแปร:

    No.ColumnData
    1IDรหัสพนักงาน
    2Nameชื่อพนักงาน
    3Departmentแผนก
    4Ageอายุ
    5Engagementคะแนนการมีส่วนร่วม (1 ถึง 100)
    6YearsAtCompanyอายุงาน
    7AttritionRiskความเสี่ยงที่จะลาออก (Low, Medium, High)
    8Salaryเงินเดือน

    Code ในการสร้างและเรียกดู hr_data:

    # Create the dataset
    hr_data <- data.frame(
      ID = 1:15,
      Name = c("Alice", "Bob", "Carol", "David", "Eve", "Frank", "Grace", 
               "Henry", "Ivy", "Jack", "Karen", "Liam", "Mona", "Nate", "Olivia"),
      Department = c("HR", "IT", "Finance", "HR", "Sales", "IT", "Finance", 
                     "Sales", "IT", "HR", "Finance", "Sales", "IT", "HR", "Sales"),
      Age = c(34, 29, 45, 50, 27, 30, 42, 35, 31, 40, 38, 28, 33, 55, 26),
      Engagement = c(85, 70, 65, 55, 90, 75, 60, 88, 80, 50, 68, 72, 78, 40, 95),
      YearsAtCompany = c(5, 2, 15, 25, 1, 3, 10, 7, 4, 20, 12, 1, 6, 30, 0),
      AttritionRisk = c("Low", "Medium", "High", "High", "Low", "Medium", "High", 
                        "Low", "Medium", "High", "High", "Low", "Medium", "High", "Low"),
      Salary = c(55000, 60000, 70000, 75000, 50000, 62000, 68000, 58000, 
                 61000, 77000, 72000, 51000, 64000, 80000, 49000)
    )
    
    # View the dataset
    hr_data
    

    ผลลัพธ์:


    ✍️ Pattern การเขียน Function

    แม้ว่าทั้ง 5 functions จะมีหน้าที่แตกต่างกัน แต่มีการเรียกใช้งานที่เหมือนกัน:

    func(dataset,
    condition)
    • func = ชื่อ function เช่น select, filter, arrange
    • dataset = ชุดข้อมูลที่เป็น input
    • condition = เงื่อนไขในการใช้งานทำงานของ function

    1️⃣ Function #1: select()

    select() ใช้เลือก column ข้อมูลที่ต้องการ

    ตัวอย่าง:

    ผู้บริหารต้องการข้อมูลที่มีแค่รายชื่อพนักงาน แผนก และคะแนนการมีส่วนร่วม

    เราสามารถใช้ select() เลือกเฉพาะ column ที่ต้องการได้:

    # Select only desired columns
    select(hr_data,
           Name,
           Department,
           Engagement)
    

    ผลลัพธ์:

    .

    Note:

    เวลาเลือก column ด้วย select() เราสามารถกำหนดลำดับของ column ที่จะมาแสดงได้ เช่น ต้องการแสดง Department ก่อน Name ก็ให้เขียน Department, Name

    .

    dplyr มี helper function ที่ช่วยในการเลือก column ให้ง่ายขึ้น เช่น:

    FunctionMeaning
    starts_with()เลือก column ที่เริ่มด้วย x
    ends_with()เลือก column ที่ลงท้ายด้วย x
    contains()เลือก column ที่มีคำว่า x
    matches()เลือก column ที่ตรงกับ regular expression
    last_col()เลือก column สุดท้ายในชุดข้อมูล
    ~เลือกทุก column ยกเว้น column ที่ระบุ

    .

    เราสามารถตั้งชื่อ column ใหม่ได้ ด้วยใช้ = เช่น FullName = Name เพื่อให้หัว column แสดงคำว่า Fullname แทน Name


    2️⃣ Function #2: filter()

    filter() ใช้เลือก row ที่ตรงกับเงื่อนไขที่กำหนดมาแสดง

    ตัวอย่าง:

    ผู้บริหารต้องการข้อมูลพนักงานที่ความเสี่ยงที่จะลาออกสูง

    เราสามารถใช้ filter() เพื่อกำหนดเงื่อนไขเพื่อกรองข้อมูลออกมาได้:

    # Filter for high attrition risk
    filter(hr_data,
           AttritionRisk == "High")
    

    ผลลัพธ์:

    .

    Note:

    เราสามารถใช้ boolean operator และ comparison operator ร่วมได้:

    OperatorMeaning
    ==เท่ากับ
    !=ไม่เท่ากับ
    >มากกว่า
    <น้อยกว่า
    &and
    |or
    !not

    เช่น:

    ผู้บริหารต้องการข้อมูลพนักงานที่ความเสี่ยงที่จะลาออกสูง ในแผนกการเงิน (Finance)

    # Filter for high attrition risk in Finance
    filter(hr_data,
           AttritionRisk == "High" & Department == "Finance")
    

    ผลลัพธ์:


    3️⃣ Function #3: arrange()

    arrange() ใช้เรียงข้อมูลตามเงื่อนไข

    ตัวอย่าง:

    ผู้บริหารอยากได้ข้อมูลพนักงานเรียงจากคะแนนการมีส่วนร่วม

    เราสามารถใช้ arrange() จัดลำดับตาม column ที่ต้องการได้:

    # Sort employees by engagement
    arrange(hr_data,
            Engagement)
    

    ผลลัพธ์:

    .

    Note:

    Default ของ arrange() เป็นเรียงจากน้อยไปมาก (A-Z)

    ถ้าต้องการเรียงจากน้อยไปมาก (Z-A) ให้ใช้ desc() เช่น:

    # Sort employees by engagement, from high to low
    arrange(hr_data,
            desc(Engagement))
    

    ผลลัพธ์:


    4️⃣ Function #4: summarise()

    summarise() ใช้ย่อยข้อมูลให้น้อยลง ช่วยให้เข้าใจข้อมูลได้ง่ายขึ้น

    ตัวอย่าง:

    ผู้บริการต้องการรู้ค่าเฉลี่ยคะแนนการมีส่วนร่วม

    เราสามารถใช้ summarise() เพื่อหาค่าเฉลี่ยได้:

    # Calculate mean engagement
    summarise(hr_data,
              mean(Engagement))
    

    ผลลัพธ์:

    .

    Note:

    Functions ที่มักใช้กับ summarise() ได้แก่:

    FunctionMeaning
    mean()หาค่าเฉลี่ย
    min()หาค่าต่ำสุด
    max()หาค่าสูงสุด
    sd()หาค่าเบี่ยงเบนมาตรฐาน (standard deviation)
    n()นับจำนวนข้อมูล

    .

    summarise() มักใช้กับ group_by() เพื่อหาค่าสถิติตามกลุ่มข้อมูล เช่น หาค่าเฉลี่ยคะแนนการทำงานตามระดับความเสี่ยงในการลาออก:

    # Calculate mean engagement by attrition risk
    summarise(group_by(hr_data, AttritionRisk),
              mean(Engagement))
    

    ผลลัพธ์:

    .

    นอกจากนี้ เราสามารถตั้งชื่อ column ของค่าสถิติได้โดยใช้ = ได้ เช่น:

    # Naming the output
    summarise(group_by(hr_data, AttritionRisk),
              AvgEng = mean(Engagement))
    

    ผลลัพธ์:


    5️⃣ Function #5: mutate()

    mutate() ใช้สำหรับสร้างข้อมูลใหม่จากข้อมูลที่มีอยู่แล้ว

    ตัวอย่าง:

    ผู้บริหารอยากรู้ว่า พนักงานแต่ละคนเหลือเวลาก่อนเกษียณอายุเท่าไร

    เราสามารถใช้ mutate() เพื่อสร้าง column ใหม่ที่แสดงจำนวนปีก่อนเกษียณได้:

    # Add a new column
    mutate(hr_data,
           YearsUntilRetirement = 60 - Age)
    

    ผลลัพธ์:

    จากผลลัพธ์ จะเห็นได้ว่า column ใหม่จะต่อท้ายสุด (ด้านขวาสุด)

    .

    Note:

    ถ้าต้องการเห็นแค่ข้อมูลใหม่ เราสามารถเปลี่ยน mutate() เป็น transmute() ได้

    โดยหลังจากได้ข้อมูลใหม่แล้ว transmute() จะทิ้งข้อมูลตั้งต้น และเก็บเฉพาะข้อมูลใหม่ไว้


    🫂 Put Everything Together: Pipe Operator

    เราจะเห็นความสามารถที่แท้จริงของ dplyr ได้เมื่อใช้งานทั้ง 5 functions ร่วมกัน โดยใช้ pipe operator: %>% หรือ |>

    Pipe operator เป็นสิ่งที่ช่วยส่ง output จาก function หนึ่งไปเป็น input ของ function ต่อไป

    เช่น จาก code หาค่าเฉลี่ยคะแนนการทำงานตามระดับความเสี่ยงในการลาออก ก่อนหน้านี้:

    # Calculate mean engagement by attrition risk
    summarise(group_by(hr_data, AttritionRisk),
              AvgEng = mean(Engagement))
    

    ถ้าใช้ pipe operator แล้ว จะเขียนได้แบบนี้:

    # Calculate mean engagement by attrition risk
    hr_data |>
      
      # Group by AttritionRisk
      group_by(AttritionRisk) |>
      
      # Calculate mean
      summarise(AvgEng = mean(Engagement))
    

    ซึ่ง code ทั้งสองชุดให้ผลลัพธ์ที่เหมือนกัน:

    แต่จะเห็นได้ว่า code ที่ใช้ pipe operator มีความชัดเจนและอ่านง่ายกว่า เพราะไม่จำเป็นต้องเขียน code ที่ซ้อนกันเป็นชั้น ๆ

    .

    ทีนี้ ถ้าเราใช้ pipe operator เพื่อรวมทั้ง 5 functions เข้าด้วยกันแล้ว จะทำให้เราใช้ข้อมูลเพื่อตอบคำถามที่ซับซ้อนขึ้นได้

    ตัวอย่าง:

    ผู้บริหารอยากได้รายชื่อพนักงานในกลุ่มเสี่ยงลาออกสูง โดยเรียงตามอายุงานและเงินเดือน จากมากไปน้อย

    เราสามารถใช้ pipe operator ร่วมกัน group_by() + summarise() + arrange() เพื่อตอบโจทย์ได้:

    # Find employees with high attrition risk
    # and sort by tenure and salary
    hr_data |>
      
      # Filter for high attrition risk
      filter(AttritionRisk == "High") |>
      
      # Sort descending by tenure and salary
      arrange(desc(YearsAtCompany),
              desc(Salary))
    

    ผลลัพธ์:

    .

    หรือ

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

    hr_data |> 
      
      # Group by department
      group_by(Department) |>
      
      # Calculate mean and count the number of employees
      summarise(AvgEng = mean(Engagement),
                EmpCount = n()) |>
      
      # Sort descending by average engagement
      arrange(desc(AvgEng))
    

    ผลลัพธ์:

    .

    หรือ

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

    hr_data |>
      
      # Group by department
      group_by(Department) |>
      
      # Count high attrition risk and find attrition risk ratio
      summarise(HighRiskCount = sum(AttritionRisk == "High"),
                TotalEmp = n(),
                HighRiskRatio = (HighRiskCount / TotalEmp) * 100) |>
      
      # Select desired columns
      select(Department, HighRiskRatio, TotalEmp, HighRiskCount) |>
      
      # Sort descending by high rish ratio
      arrange(desc(HighRiskRatio))
    

    ผลลัพธ์:


    🔥 สรุป 5 Functions จาก dplyr

    5 functions พื้นฐาน ของ dplyr เป็น functions ที่สามารถใช้ร่วมกันเพื่อทำงานกับข้อมูลต่าง ๆ เช่น ข้อมูลพนักงาน ได้อย่างมีประสิทธิภาพ

    No.FunctionExplain
    1select()เลือก column ที่ต้องการ
    2filter()เลือก row ที่ต้องการ
    3arrange()จัดลำดับข้อมูล
    4sumamrise()สรุปข้อมูล
    5mutate()แปลงข้อมูล

    Note: ใช้ %>% หรือ |> เพื่อเชื่อม functions เข้าด้วยกัน


    💪 Try It Yourself

    สำหรับใครที่อยากลองเล่นใช้ R เล่นกับข้อมูล HR สามารถดาวน์โหลด code ตัวอย่างในบทความได้ที่ GitHub


    📚 อ่านเพิ่มเติมเกี่ยวกับ dplyr


    ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    📕 ขอฝากหนังสือเล่มแรกในชีวิตด้วยนะครับ 😆

    🙋 ใครที่กำลังเรียนจิตวิทยาหรือทำงานสายจิตวิทยา และเบื่อที่ต้องใช้ software ราคาแพงอย่าง SPSS และ Excel เพื่อทำข้อมูล

    💪 ผมขอแนะนำ R Book for Psychologists หนังสือสอนใช้ภาษา R เพื่อการวิเคราะห์ข้อมูลทางจิตวิทยา ที่เขียนมาเพื่อนักจิตวิทยาที่ไม่เคยมีประสบการณ์เขียน code มาก่อน

    ในหนังสือ เราจะปูพื้นฐานภาษา R และพาไปดูวิธีวิเคราะห์สถิติที่ใช้บ่อยกัน เช่น:

    • Correlation
    • t-tests
    • ANOVA
    • Reliability
    • Factor analysis

    🚀 เมื่ออ่านและทำตามตัวอย่างใน R Book for Psychologists ทุกคนจะไม่ต้องพึง SPSS และ Excel ในการทำงานอีกต่อไป และสามารถวิเคราะห์ข้อมูลด้วยตัวเองได้ด้วยความมั่นใจ

    แล้วทุกคนจะแปลกใจว่า ทำไมภาษา R ง่ายขนาดนี้ 🙂‍↕️

    👉 สนใจดูรายละเอียดหนังสือได้ที่ meb: