Author: Shinin Varongchayakul

  • วิธีใช้ 9 arguments ใน read_csv() จาก pandas library เพื่อโหลดข้อมูลใน Python — ตัวอย่างการโหลดข้อมูลการแข่งขันฟุตบอล

    วิธีใช้ 9 arguments ใน read_csv() จาก pandas library เพื่อโหลดข้อมูลใน Python — ตัวอย่างการโหลดข้อมูลการแข่งขันฟุตบอล

    pandas เป็น Python library สำหรับทำงานกับข้อมูลในรูปแบบตาราง (tabular data) และมี functions หลากหลายสำหรับโหลดข้อมูลเข้ามาใน Python

    โดยหนึ่งใน functions ที่นิยมใช้กันมากที่สุด ได้แก่ read_csv() ซึ่งใช้โหลดข้อมูล CSV (Comma-Separated Values) และมี arguments หลัก 9 อย่าง ได้แก่:

    1. filepath_or_buffer: file path, ชื่อไฟล์, หรือ URL ของไฟล์ที่ต้องการโหลด
    2. sep: กำหนด delimiter
    3. header: กำหนด row ที่เป็นหัวตาราง
    4. skiprows: กำหนด rows ที่ไม่ต้องการโหลด
    5. nrows: เลือกจำนวน rows ที่ต้องการโหลด
    6. usecols: กำหนด columns ที่ต้องการโหลด
    7. index_col: กำหนด column ที่จะเป็น index
    8. names: กำหนดชื่อของ columns
    9. dtype: กำหนดประเภทข้อมูล (data types) ของ columns

    ในบทความนี้ เราจะมาดูวิธีใช้ทั้ง 9 arguments ของ read_csv() เพื่อโหลดตัวอย่างข้อมูลการแข่งขันฟุตบอลในอังกฤษกัน

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


    1. 🏁 Getting Started
    2. 🗃️ Argument #1. filepath_or_buffer
    3. 🤺 Argument #2. sep
    4. 😶‍🌫️ Argument #3. header
    5. 🛑 Argument #4. skiprows
    6. 📋 Argument #5. nrows
    7. ☑️ Argument #6. usecols
    8. 🔢 Argument #7. index_col
    9. 🔠 Argument #8. names
    10. ⏹️ Argument #9. dtype
    11. ⚡ Summary
    12. 😺 GitHub
    13. 📃 References

    🏁 Getting Started

    ก่อนเริ่มใช้งาน read_csv() เราต้องติดตั้งและโหลด pandas ก่อน:

    # Install pandas
    !pip install pandas
    
    # Import pandas
    import pandas as pd
    

    Note: ในกรณีที่เราเคยติดตั้ง pandas แล้วให้ใช้คำสั่ง import อย่างเดียว


    🗃️ Argument #1. filepath_or_buffer

    filepath_or_buffer เป็น argument หลักที่เราจะต้องกำหนดทุกครั้งที่เรียกใช้ read_csv()

    ยกตัวอย่างเช่น เรามีข้อมูลการแข่งขันฟุตบอล (matches_clean.csv):

    MatchID,HomeTeam,AwayTeam,HomeGoals,AwayGoals,MatchDate
    M001,Manchester United,Chelsea,2,1,2024-08-14
    M002,Liverpool,Arsenal,1,1,2024-08-20
    M003,Tottenham,Everton,3,0,2024-09-02
    M004,Man City,Aston Villa,4,2,2024-09-15
    M005,Newcastle,West Ham,0,0,2024-09-22
    M006,Brighton,Leeds,2,3,2024-09-29
    

    เราสามารถใช้ read_csv() ได้แบบนี้:

    # Load the dataset
    df1 = pd.read_csv("matches_clean.csv")
    
    # View the result
    print(df1)
    

    ผลลัพธ์:

      MatchID           HomeTeam     AwayTeam  HomeGoals  AwayGoals   MatchDate
    0    M001  Manchester United      Chelsea          2          1  2024-08-14
    1    M002          Liverpool      Arsenal          1          1  2024-08-20
    2    M003          Tottenham      Everton          3          0  2024-09-02
    3    M004           Man City  Aston Villa          4          2  2024-09-15
    4    M005          Newcastle     West Ham          0          0  2024-09-22
    5    M006           Brighton        Leeds          2          3  2024-09-29
    

    🤺 Argument #2. sep

    sep ใช้กำหนด delimiter หรือเครื่องหมายในการแบ่ง columns โดย default ของ sep คือ "," ทำให้ปกติ เราไม่ต้องกำหนด sep เมื่อไฟล์เป็น CSV

    เราจะใช้ sep เมื่อข้อมูลมี delimiter อื่น เช่น ";" (matches_semicolon.txt):

    MatchID;HomeTeam;AwayTeam;HomeGoals;AwayGoals;MatchDate
    M001;Manchester United;Chelsea;2;1;2024-08-14
    M002;Liverpool;Arsenal;1;1;2024-08-20
    M003;Tottenham;Everton;3;0;2024-09-02
    M004;Man City;Aston Villa;4;2;2024-09-15
    M005;Newcastle;West Ham;0;0;2024-09-22
    M006;Brighton;Leeds;2;3;2024-09-29
    

    เราสามารถใช้ sep ได้แบบนี้:

    # Load the dataset with ";" as delim
    df2 = pd.read_csv("matches_semicolon.csv", sep=";")
    
    # View the result
    print(df2)
    

    ผลลัพธ์:

      MatchID           HomeTeam     AwayTeam  HomeGoals  AwayGoals   MatchDate
    0    M001  Manchester United      Chelsea          2          1  2024-08-14
    1    M002          Liverpool      Arsenal          1          1  2024-08-20
    2    M003          Tottenham      Everton          3          0  2024-09-02
    3    M004           Man City  Aston Villa          4          2  2024-09-15
    4    M005          Newcastle     West Ham          0          0  2024-09-22
    5    M006           Brighton        Leeds          2          3  2024-09-29
    

    😶‍🌫️ Argument #3. header

    header ใช้กำหนด row ที่จะเป็นหัวตาราง

    เราจะใช้ header เมื่อ rows แรกของข้อมูลมีข้อมูลอื่น เช่น metadata (matches_with_metadata.txt):

    # UK Football Matches Data
    # Created for practice with pd.read_csv()
    MatchID,HomeTeam,AwayTeam,HomeGoals,AwayGoals,MatchDate
    M001,Manchester United,Chelsea,2,1,2024-08-14
    M002,Liverpool,Arsenal,1,1,2024-08-20
    M003,Tottenham,Everton,3,0,2024-09-02
    M004,Man City,Aston Villa,4,2,2024-09-15
    M005,Newcastle,West Ham,0,0,2024-09-22
    M006,Brighton,Leeds,2,3,2024-09-29
    

    เราสามารถใช้ header ได้แบบนี้:

    # Load the dataset where the header is the 3rd row
    df3 = pd.read_csv("matches_with_metadata.txt", header=2)
    
    # View the result
    print(df3)
    

    ผลลัพธ์:

      MatchID           HomeTeam     AwayTeam  HomeGoals  AwayGoals   MatchDate
    0    M001  Manchester United      Chelsea          2          1  2024-08-14
    1    M002          Liverpool      Arsenal          1          1  2024-08-20
    2    M003          Tottenham      Everton          3          0  2024-09-02
    3    M004           Man City  Aston Villa          4          2  2024-09-15
    4    M005          Newcastle     West Ham          0          0  2024-09-22
    5    M006           Brighton        Leeds          2          3  2024-09-29
    

    จะสังเกตว่า metadata จะไม่ถูกโหลดเข้ามาด้วย

    Note: เราสามารถกำหนด header=None ในกรณีที่ข้อมูลไม่มีหัวตาราง เช่น matches_no_header.csv:

    M001,Manchester United,Chelsea,2,1,2024-08-14
    M002,Liverpool,Arsenal,1,1,2024-08-20
    M003,Tottenham,Everton,3,0,2024-09-02
    M004,Man City,Aston Villa,4,2,2024-09-15
    M005,Newcastle,West Ham,0,0,2024-09-22
    M006,Brighton,Leeds,2,3,2024-09-29
    

    🛑 Argument #4. skiprows

    skiprows ใช้เลือก rows ที่เราไม่ต้องการโหลดเข้ามาใน Python ซึ่งเราสามารถกำหนดได้ 2 แบบ:

    1. กำหนดเป็น int (เช่น 2) ในกรณีที่ต้องการข้าม row เดียว
    2. กำหนดเป็น list (เช่น [0, 1, 2]) ในกรณีที่ต้องการข้ามมากกว่า 1 rows

    ยกตัวอย่างเช่น เราต้องการข้าม 2 บรรทัดแรกซึ่งเป็น metadata:

    # UK Football Matches Data
    # Created for practice with pd.read_csv()
    MatchID,HomeTeam,AwayTeam,HomeGoals,AwayGoals,MatchDate
    M001,Manchester United,Chelsea,2,1,2024-08-14
    M002,Liverpool,Arsenal,1,1,2024-08-20
    M003,Tottenham,Everton,3,0,2024-09-02
    M004,Man City,Aston Villa,4,2,2024-09-15
    M005,Newcastle,West Ham,0,0,2024-09-22
    M006,Brighton,Leeds,2,3,2024-09-29
    

    เราสามารถใช้ skiprows ได้แบบนี้:

    # Load the dataset, skipping the metadata
    df4 = pd.read_csv("matches_with_metadata.txt", skiprows=[0, 1])
    
    # View the result
    print(df4)
    

    ผลลัพธ์:

      MatchID           HomeTeam     AwayTeam  HomeGoals  AwayGoals   MatchDate
    0    M001  Manchester United      Chelsea          2          1  2024-08-14
    1    M002          Liverpool      Arsenal          1          1  2024-08-20
    2    M003          Tottenham      Everton          3          0  2024-09-02
    3    M004           Man City  Aston Villa          4          2  2024-09-15
    4    M005          Newcastle     West Ham          0          0  2024-09-22
    5    M006           Brighton        Leeds          2          3  2024-09-29
    

    📋 Argument #5. nrows

    nrows ใช้เลือก rows ที่เราต้องการโหลดเข้ามาใน Python

    เช่น แทนที่จะโหลดข้อมูลทั้งหมด:

    MatchID,HomeTeam,AwayTeam,HomeGoals,AwayGoals,MatchDate
    M001,Manchester United,Chelsea,2,1,2024-08-14
    M002,Liverpool,Arsenal,1,1,2024-08-20
    M003,Tottenham,Everton,3,0,2024-09-02
    M004,Man City,Aston Villa,4,2,2024-09-15
    M005,Newcastle,West Ham,0,0,2024-09-22
    M006,Brighton,Leeds,2,3,2024-09-29
    

    เราจะโหลดข้อมูล 3 rows แรกด้วย nrows แบบนี้:

    # Load the first 3 rows
    df5 = pd.read_csv("matches_clean.csv", nrows=3)
    
    # View the result
    print(df5)
    

    ผลลัพธ์:

      MatchID           HomeTeam AwayTeam  HomeGoals  AwayGoals   MatchDate
    0    M001  Manchester United  Chelsea          2          1  2024-08-14
    1    M002          Liverpool  Arsenal          1          1  2024-08-20
    2    M003          Tottenham  Everton          3          0  2024-09-02
    

    ☑️ Argument #6. usecols

    usecols ใช้กำหนด columns ที่เราต้องการโหลดเข้ามาใน Python

    ยกตัวอย่างเช่น เลือกเฉพาะ HomeTeam และ HomeGoals จาก:

    MatchID,HomeTeam,AwayTeam,HomeGoals,AwayGoals,MatchDate
    M001,Manchester United,Chelsea,2,1,2024-08-14
    M002,Liverpool,Arsenal,1,1,2024-08-20
    M003,Tottenham,Everton,3,0,2024-09-02
    M004,Man City,Aston Villa,4,2,2024-09-15
    M005,Newcastle,West Ham,0,0,2024-09-22
    M006,Brighton,Leeds,2,3,2024-09-29
    

    เราสามารถใช้ usecols ได้แบบนี้:

    # Load only HomeTeam and HomeGoals
    df6 = pd.read_csv("matches_clean.csv", usecols=["HomeTeam", "HomeGoals"])
    
    # View the result
    print(df6)
    

    ผลลัพธ์:

                HomeTeam  HomeGoals
    0  Manchester United          2
    1          Liverpool          1
    2          Tottenham          3
    3           Man City          4
    4          Newcastle          0
    5           Brighton          2
    

    🔢 Argument #7. index_col

    index_col ใช้กำหนด column ที่เป็น index ของข้อมูล เช่น MatchID:

    MatchID,HomeTeam,AwayTeam,HomeGoals,AwayGoals,MatchDate
    M001,Manchester United,Chelsea,2,1,2024-08-14
    M002,Liverpool,Arsenal,1,1,2024-08-20
    M003,Tottenham,Everton,3,0,2024-09-02
    M004,Man City,Aston Villa,4,2,2024-09-15
    M005,Newcastle,West Ham,0,0,2024-09-22
    M006,Brighton,Leeds,2,3,2024-09-29
    

    เราจะใช้ index_col แบบนี้:

    # Load the dataset with MatchID as index col
    df7 = pd.read_csv("matches_clean.csv", index_col="MatchID")
    
    # View the result
    print(df7)
    

    ผลลัพธ์:

                      HomeTeam     AwayTeam  HomeGoals  AwayGoals   MatchDate
    MatchID
    M001     Manchester United      Chelsea          2          1  2024-08-14
    M002             Liverpool      Arsenal          1          1  2024-08-20
    M003             Tottenham      Everton          3          0  2024-09-02
    M004              Man City  Aston Villa          4          2  2024-09-15
    M005             Newcastle     West Ham          0          0  2024-09-22
    M006              Brighton        Leeds          2          3  2024-09-29
    

    🔠 Argument #8. names

    names ใช้กำหนดชื่อ columns ซึ่งเราจะใช้เมื่อ:

    • ข้อมูลไม่มีหัวตาราง
    • ต้องการเปลี่ยนชื่อ columns

    ยกตัวอย่างเช่น ใส่ชื่อ columns ให้กับ matches_no_header.csv:

    M001,Manchester United,Chelsea,2,1,2024-08-14
    M002,Liverpool,Arsenal,1,1,2024-08-20
    M003,Tottenham,Everton,3,0,2024-09-02
    M004,Man City,Aston Villa,4,2,2024-09-15
    M005,Newcastle,West Ham,0,0,2024-09-22
    M006,Brighton,Leeds,2,3,2024-09-29
    

    เราสามารถใช้ names ได้แบบนี้:

    # Set col names
    col_names = [
        "id",
        "home",
        "away",
        "home_goals",
        "away_goals",
        "date"
    ]
    
    # Load the dataset with custom col names
    df8 = pd.read_csv("matches_no_header.csv", names=col_names)
    
    # View the result
    print(df8)
    

    ผลลัพธ์:

         id               home         away  home_goals  away_goals        date
    0  M001  Manchester United      Chelsea           2           1  2024-08-14
    1  M002          Liverpool      Arsenal           1           1  2024-08-20
    2  M003          Tottenham      Everton           3           0  2024-09-02
    3  M004           Man City  Aston Villa           4           2  2024-09-15
    4  M005          Newcastle     West Ham           0           0  2024-09-22
    5  M006           Brighton        Leeds           2           3  2024-09-29
    

    ⏹️ Argument #9. dtype

    dtype ใช้กำหนดประเภทข้อมูลของ columns

    ยกตัวอย่างเช่น กำหนด ประเภทข้อมูลของ MatchID, HomeGoals, และ AwayGoals จาก matches_clean.csv:

    MatchID,HomeTeam,AwayTeam,HomeGoals,AwayGoals,MatchDate
    M001,Manchester United,Chelsea,2,1,2024-08-14
    M002,Liverpool,Arsenal,1,1,2024-08-20
    M003,Tottenham,Everton,3,0,2024-09-02
    M004,Man City,Aston Villa,4,2,2024-09-15
    M005,Newcastle,West Ham,0,0,2024-09-22
    M006,Brighton,Leeds,2,3,2024-09-29
    

    เราสามารถใช้ dtype ได้แบบนี้:

    # Set col data types
    col_dtypes = {
        "MatchID": str,
        "HomeGoals": "int32",
        "AwayGoals": "int32"
    }
    
    # Load the dataset, specifying data types for MatchID, HomeGoals, and AwayGoals
    df9 = pd.read_csv("matches_clean.csv", dtype=col_dtypes)
    
    # View the result
    df9.info()
    

    ผลลัพธ์:

    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 6 entries, 0 to 5
    Data columns (total 6 columns):
     #   Column     Non-Null Count  Dtype
    ---  ------     --------------  -----
     0   MatchID    6 non-null      object
     1   HomeTeam   6 non-null      object
     2   AwayTeam   6 non-null      object
     3   HomeGoals  6 non-null      int32
     4   AwayGoals  6 non-null      int32
     5   MatchDate  6 non-null      object
    dtypes: int32(2), object(4)
    memory usage: 372.0+ bytes
    

    ⚡ Summary

    ในบทความนี้ เราได้ไปดูวิธีการใช้ 9 arguments ของ read_csv() จาก pandas เพื่อโหลดข้อมูลใน Python กัน:

    1. filepath_or_buffer: ไฟล์ที่ต้องการโหลด
    2. sep: delimiter ในไฟล์
    3. header: row ที่เป็นหัวตาราง
    4. skiprows: rows ที่ไม่ต้องการโหลด
    5. nrows: จำนวน rows ที่ต้องการโหลด
    6. usecols: columns ที่ต้องการโหลด
    7. index_col: column ที่จะเป็น index
    8. names: ชื่อของ columns
    9. dtype: ประเภทข้อมูล (data types) ของ columns

    😺 GitHub

    ดูตัวอย่าง code และ datasets ทั้งหมดได้ที่ GitHub


    📃 References

  • แนะนำ 4 functions ในการทำงานกับ JSON ใน Python: json.dumps(), json.loads(), json.dump(), และ json.load() — ตัวอย่างการทำงานกับข้อมูลคำสั่งซื้อคุกกี้

    แนะนำ 4 functions ในการทำงานกับ JSON ใน Python: json.dumps(), json.loads(), json.dump(), และ json.load() — ตัวอย่างการทำงานกับข้อมูลคำสั่งซื้อคุกกี้

    ในบทความนี้ เราจะไปดูวิธีใช้ 4 functions จาก json package ใน Python สำหรับทำงานกับ JSON (JavaScript Object Notation) ซึ่งเป็น data structure ที่พบได้บ่อยในแอปพลิเคชันและระบบต่าง ๆ กัน:

    1. json.loads()
    2. json.dumps()
    3. json.load()
    4. json.dump()

    ตัวอย่าง JSON คำสั่งซื้อออนไลน์:

    {
      "order_id": 1024,
      "customer": {
        "name": "Ari Lee",
        "phone": "+66 89 123 4567"
      },
      "items": [
        {
          "product": "Cappuccino",
          "size": "Medium",
          "price": 75,
          "quantity": 1
        },
        {
          "product": "Ham Sandwich",
          "price": 95,
          "quantity": 2
        }
      ],
      "payment": {
        "method": "QR Code",
        "total": 170,
        "currency": "THB"
      },
      "status": "Preparing",
      "timestamp": "2025-10-11T09:30:00"
    }
    

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


    1. 🏁 Introduction to json
    2. 🗨️ Group 1. JSON Strings
      1. ⬇️ json.loads(): JSON String to Python Object
      2. ⬆️ json.dumps(): Python Object to JSON String
    3. 📂 Group 2. JSON Files
      1. ⬇️ json.load(): JSON File to Python Object
      2. ⬆️ json.dump(): Python Object to JSON File
    4. 💪 Summary
    5. 😺 GitHub
    6. 📃 References

    🏁 Introduction to json

    json เป็น built-in package ใน Python และถูกออกแบบมาสำหรับทำงานกับ JSON โดยเฉพาะ

    เราสามารถเริ่มใช้งาน json ด้วยการโหลด package ด้วย import:

    # Import json
    import json
    

    json มี 4 functions สำหรับทำงานกับ JSON ซึ่งแบ่งได้เป็น 2 กลุ่ม:

    1. ทำงานกับ JSON string หรือ JSON ที่อยู่ในรูป Python string:
      1. json.loads()
      2. json.dumps()
    2. ทำงานกับ JSON file หรือ file ที่เห็นข้อมูล JSON เอาไว้:
      1. json.load()
      2. json.dump()

    Note: เทคนิคการจำ คือ function ที่ลงท้ายด้วย s (เช่น json.loads()) แสดงว่าใช้งานกับ JSON string

    ทั้ง 4 functions มีรายละเอียดการใช้งาน ดังนี้:

    FunctionFromTo
    json.loads()JSON string 🗨️Python object 🐍
    json.dumps()Python object 🐍JSON string 🗨️
    json.load()JSON file 📂Python object 🐍
    json.dump()Python object 🐍JSON file 📂

    เราไปดูวิธีใช้งานทั้ง 4 functions กับตัวอย่างข้อมูลสั่งซื้อคุกกี้กัน


    🗨️ Group 1. JSON Strings

    2 functions สำหรับทำงานกับ JSON string หรือ JSON ที่อยู่ในรูปของ Python string ได้แก่:

    FunctionFromTo
    json.loads()JSON string 🗨️Python object 🐍
    json.dumps()Python object 🐍JSON string 🗨️

    .

    ⬇️ json.loads(): JSON String to Python Object

    json.loads() ใช้โหลด JSON string ให้เป็น Python object เช่น:

    • String: ""
    • List: []
    • Dictionary: {}

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

    # Create a Python dict
    cookie_json_string = """
    {
        "customer": "May",
        "cookies": [
            "Chocolate Chip",
            "Oatmeal",
            "Sugar"
        ],
        "is_member": true,
        "total_price": 120
    }
    """
    
    # Convert to Python object
    cookie_python_dict = json.loads(cookie_json_string)
    

    เราสามารถดูผลลัพธ์ได้ด้วย pprint() ซึ่งเป็น function สำหรับ print Python dictionary ให้อ่านง่าย:

    # Import pprint
    from pprint import pprint
    
    # View the result
    pprint(cookie_python_dict)
    

    ผลลัพธ์:

    {'cookies': ['Chocolate Chip', 'Oatmeal', 'Sugar'],
     'customer': 'May',
     'is_member': True,
     'total_price': 120}
    

    .

    ⬆️ json.dumps(): Python Object to JSON String

    ในกรณีที่เรามี Python object เราสามารถแปลงเป็น JSON string ได้ด้วย json.dumps():

    # Create a Python dict
    cookie_py_dict = {
        "customer": "May",
        "cookies": [
            "Chocolate Chip",
            "Oatmeal",
            "Sugar"
        ],
        "is_member": True,
        "total_price": 120
    }
    
    # Convert to JSON string
    cookie_json_str = json.dumps(cookie_py_dict)
    
    # View the result
    print(cookie_json_str)
    

    ผลลัพธ์:

    {"customer": "May", "cookies": ["Chocolate Chip", "Oatmeal", "Sugar"], "is_member": true, "total_price": 120}
    

    ทั้งนี้ เราสามารถใช้ indent เพื่อทำให้ JSON string อ่านง่ายขึ้นได้ เช่น:

    # Convert to JSON string with indent argument
    cookie_json_str_indent = json.dumps(cookie_py_dict, indent=4)
    
    # View the result
    print(cookie_json_str_indent)
    

    ผลลัพธ์:

    {
        "customer": "May",
        "cookies": [
            "Chocolate Chip",
            "Oatmeal",
            "Sugar"
        ],
        "is_member": true,
        "total_price": 120
    }
    

    📂 Group 2. JSON Files

    เรามี 2 functions สำหรับทำงานกับ JSON files ได้แก่:

    FunctionFromTo
    json.load()JSON file 📂Python object 🐍
    json.dump()Python object 🐍JSON file 📂

    .

    ⬇️ json.load(): JSON File to Python Object

    json.load() ใช้สำหรับโหลดข้อมูลจาก JSON file เข้ามาใน Python

    เช่น เรามี JSON file ดังนี้:

    {
        "order_id": 2048,
        "customer": {
            "name": "MJ",
            "phone": "+66 92 888 4321"
        },
        "items": [
            {
                "product": "Double Chocolate Cookie",
                "size": "Large",
                "price": 55,
                "quantity": 2
            },
            {
                "product": "Almond Biscotti",
                "price": 45,
                "quantity": 3
            }
        ],
        "payment": {
            "method": "Credit Card",
            "total": 285,
            "currency": "THB"
        },
        "status": "Baking",
        "timestamp": "2025-10-11T10:15:00"
    }
    

    เราสามารถโหลดขัอมูลได้แบบนี้:

    # Load JSON data
    with open("cookie_order.json", "r") as file:
        cookie_order = json.load(file)
    
    # View the result
    pprint(cookie_order)
    

    ผลลัพธ์:

    {'customer': {'name': 'MJ', 'phone': '+66 92 888 4321'},
     'items': [{'price': 55,
                'product': 'Double Chocolate Cookie',
                'quantity': 2,
                'size': 'Large'},
               {'price': 45, 'product': 'Almond Biscotti', 'quantity': 3}],
     'order_id': 2048,
     'payment': {'currency': 'THB', 'method': 'Credit Card', 'total': 285},
     'status': 'Baking',
     'timestamp': '2025-10-11T10:15:00'}
    

    .

    ⬆️ json.dump(): Python Object to JSON File

    json.dump() ใช้สร้าง JSON file จาก Python objects

    เช่น update ข้อมูลผู้ซื้อใน cookie_order จาก "MJ" เป็น "Peter Parker" และสร้างเป็น JSON file:

    # Update name
    cookie_order["customer"]["name"] = "Peter Parker"
    
    # Write to JSON file
    with open("cookie_order_updated.json", "w") as file:
        json.dump(cookie_order, file, indent=2)
    

    Note: สังเกตว่า เราสามารถกำหนด indent เพื่อทำให้ JSON อ่านง่ายขึ้นได้เหมือนกับ json.dumps()

    ผลลัพธ์ใน JSON file:

    {
      "order_id": 2048,
      "customer": {
        "name": "Peter Parker",
        "phone": "+66 92 888 4321"
      },
      "items": [
        {
          "product": "Double Chocolate Cookie",
          "size": "Large",
          "price": 55,
          "quantity": 2
        },
        {
          "product": "Almond Biscotti",
          "price": 45,
          "quantity": 3
        }
      ],
      "payment": {
        "method": "Credit Card",
        "total": 285,
        "currency": "THB"
      },
      "status": "Baking",
      "timestamp": "2025-10-11T10:15:00"
    }
    

    💪 Summary

    ในบทความนี้ เราได้ไปดูวิธีการใช้ 4 functions จาก json package เพื่อทำงานกับ JSON ใน Python:

    FunctionFromTo
    json.loads()JSON string 🗨️Python object 🐍
    json.dumps()Python object 🐍JSON string 🗨️
    json.load()JSON file 📂Python object 🐍
    json.dump()Python object 🐍JSON file 📂

    Note: json.dumps() และ json.dump() มี indent argument ที่ทำให้ JSON ออกอ่านง่ายได้


    😺 GitHub

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


    📃 References

  • วิธีใช้ open() เพื่อทำงานกับไฟล์ใน Python: วิธีใช้งาน, วิธีเขียนโดยใช้ with และไม่ใช้ with, และ 4 modes ในการทำงานกับไฟล์ (+ bonus การลบไฟล์) พร้อมตัวอย่าง

    วิธีใช้ open() เพื่อทำงานกับไฟล์ใน Python: วิธีใช้งาน, วิธีเขียนโดยใช้ with และไม่ใช้ with, และ 4 modes ในการทำงานกับไฟล์ (+ bonus การลบไฟล์) พร้อมตัวอย่าง

    ในบทความนี้ เราจะมาดูวิธีใช้ open() เพื่อทำงานกับไฟล์ใน Python กัน:

    1. Intro to open(): วิธีการเขียนและการใช้งาน
    2. 4 modes: 4 วิธีการทำงานกับไฟล์
    3. Bonus: วิธีลบไฟล์

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


    1. 💻 Intro to open()
      1. 🔢 Syntax
      2. 🗄️ Using open()
    2. 🗂️ Mode
      1. 📄 Create
      2. 📖 Read
      3. ➕ Append
      4. ✏️ Write
    3. 🍩 Bonus: Delete
    4. ⚡ Summary
    5. 😺 GitHub
    6. 📃 References

    💻 Intro to open()

    .

    🔢 Syntax

    open() เป็น base function สำหรับทำงานกับไฟล์ และต้องการ 2 arguments:

    open(filename, mode)
    
    • filename = ชื่อไฟล์ (เป็น string เช่น "my_file.txt")
    • mode = mode ในการทำงานกับไฟล์ (เช่น "r" สำหรับอ่านไฟล์)

    .

    🗄️ Using open()

    เราสามารถใช้ open() ได้ 2 วิธี ได้แก่:

    วิธีที่ 1. เปิดไฟล์โดยไม่ใช้ with ซึ่งจะต้องมี .close() เพื่อปิดไฟล์เมื่อทำงานเสร็จ:

    # Open file
    file = open(filename, mode)
    
    # Act on file
    file.method()
    
    # Close file
    file.close()
    

    วิธีที่ 2. เปิดไฟล์โดยใช้ with:

    # Open file
    with open(filename, mode) as file:
        
        # Act on file
        file.method()
    

    วิธีที่ 2 เป็นวิธีที่นิยมใช้มากกว่า เพราะเราไม่จำเป็นต้องปิดไฟล์ด้วย .close() หลังทำงานเสร็จ


    🗂️ Mode

    open() มี 4 modes ในการทำงานกับไฟล์ ได้แก่:

    ModeActionNote
    "x"สร้างไฟล์แสดง error ถ้ามีไฟล์ชื่อเดียวกันอยู่แล้ว
    "r"อ่านไฟล์แสดง error ถ้ามีไม่มีไฟล์ที่ต้องการ
    "a"เพิ่มข้อมูลในไฟล์สร้างไฟล์ใหม่ถ้าไม่มีไฟล์ชื่อเดียวกันอยู่แล้ว
    "w"เขียนทับข้อมูลที่มีในไฟล์สร้างไฟล์ใหม่ถ้าไม่มีไฟล์ชื่อเดียวกันอยู่แล้ว

    ไปดูตัวอย่างการใช้ทั้ง 4 modes กัน

    .

    📄 Create

    ตัวอย่างการสร้างไฟล์ด้วย "x":

    # Create a file
    with open("example.txt", "x") as file:
        file.write("This is the first line.")
        file.write("This is the second line.")
        file.write("This is the third line.")
    

    ผลลัพธ์: เราจะได้ไฟล์ชื่อ example.txt ในเครื่องของเรา

    .

    📖 Read

    เราสามารถอ่านไฟล์ด้วย "r" ได้ 3 วิธี:

    วิธีที่ 1. ใช้ .read() เพื่ออ่านเนื้อหาทั้งหมด:

    # Read the file - all
    with open("example.txt", "r") as file:
        file.read()
    

    ผลลัพธ์ใน console:

    This is the first line.
    This is the second line.
    This is the third line.
    

    วิธีที่ 2. ใช้ .readline() ในกรณีที่ต้องการอ่านรายบรรทัด:

    # Read the file - one line at a time
    with open("example.txt", "r") as file:
        file.readline()
        file.readline()
    

    ผลลัพธ์ใน console:

    This is the first line.
    This is the second line.
    

    วิธีที่ 3. ใช้ for loop เพื่ออ่านเนื้อหาทั้งหมดทีละบรรทัด:

    # Read the file - line by line
    with open("example.txt", "r") as file:
        
        # Loop through each line
        for line in file:
            print(line)
    

    ผลลัพธ์ใน console:

    This is the first line.
    This is the second line.
    This is the third line.
    

    .

    ➕ Append

    ตัวอย่างการเพิ่มข้อมูลด้วย "a":

    # Add content to the file
    with open("example.txt", "a") as file:
        file.write("This is the fourth line.")
    

    เนื้อหาในไฟล์:

    This is the first line.
    This is the second line.
    This is the third line.
    This is the fourth line.
    

    .

    ✏️ Write

    ตัวอย่างการเขียนไฟล์ด้วย "w":

    # Overwrite the file
    with open("example.txt", "w") as file:
        file.write("This is all there is now.")
    

    เนื้อหาในไฟล์:

    This is all there is now.
    

    🍩 Bonus: Delete

    ในกรณีที่เราต้องการลบไฟล์ เราจะต้องเรียกใช้ remove() function จาก os module:

    # Import os module
    import os
    
    # Delete the file
    os.remove("example.txt")
    

    ผลลัพธ์: ไฟล์จะถูกลบออกจากเครื่อง


    ⚡ Summary

    • open() เป็น base Python function สำหรับทำงานกับไฟล์
    • open() ต้องการ 2 arguments คือ:
      • filename: ชื่อไฟล์
      • mode: mode ในการทำงานกับไฟล์
    • วิธีใช้งาน:
      • open() มักใช้คู่กับ with
      • ถ้าไม่ใช้ with เราจะต้องปิดไฟล์ด้วย .close() เมื่อมช้งานเสร็จ
    • open() มี 4 modes ได้แก่:
      • "x": สร้างไฟล์
      • "r": อ่านไฟล์
      • "a": เพิ่มเนื้อหา
      • "w": เขียนทับข้อมูลเดิม
    • ลบไฟล์ด้วย os.remove()

    😺 GitHub

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


    📃 References

  • วิธีสร้าง functions ใน Python: def, docstring, arguments, และ lambda พร้อมตัวอย่าง

    วิธีสร้าง functions ใน Python: def, docstring, arguments, และ lambda พร้อมตัวอย่าง

    ในบทความนี้ เราจะมาดูวิธีสร้าง function ใน Python กัน โดยบทความนี้แบ่งเป็น 4 ส่วน:

    1. def syntax: การใช้ def เพื่อสร้าง function
    2. Docstring: การเขียนวิธีใช้งาน function
    3. Arguments: การกำหนด arguments ใน function
    4. lambda: การสร้าง function แบบไม่ระบุชื่อ

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


    1. 💻 def Syntax
    2. 📃 Docstring
      1. 🤔 Why Docstring?
      2. 🥸 What Is Docstring?
      3. 😎 Reading Docstring
    3. 💬 Arguments
      1. 🫡 Default Arguments
      2. 😶‍🌫️ Arbitrary Arguments
    4. 🛋️ lambda
    5. 😺 GitHub
    6. 📃 References

    💻 def Syntax

    ใน Python เราสามารถสร้าง function ได้ด้วย def ซึ่งประกอบด้วย 4 ส่วน:

    # Name and arguments
    def name(arguments):
        
        # Body
        Do something
        
        # Return
        return result
    1. name = ชื่อ function
    2. arguments = input สำหรับ function
    3. Body = การทำงานของ function
    4. Return = ส่งผลลัพธ์กลับออกมาจาก function *

    (Note: * เราสามารถใช้ print() แทน return ได้ ในกรณีที่เราต้องการแสดงผลลัพธ์ใน console)

    ยกตัวอย่างเช่น สร้าง function สำหรับคำนวณ BMI (body mass index) ซึ่งต้องการ 2 arguments คือ น้ำหนัก (weight) และส่วนสูง (height):

    # Create a function that calculates BMI
    def calculate_bmi(weight, height):
    
        # Calculate BMI
        bmi = weight / (height ** 2)
    
        # Round to 2 decimals
        bmi_rounded = round(bmi, 2)
    
        # Return BMI
        return bmi_rounded
    

    เราสามารถเรียกใช้ function ที่สร้างเสร็จแล้ว ด้วยการเรียกใช้ชื่อ function เช่น:

    # Use the BMI calculator function
    my_bmi = calculate_bmi(weight=80, height=1.8)
    
    # Print the result
    print(my_bmi)
    

    ผลลัพธ์:

    24.69
    

    📃 Docstring

    .

    🤔 Why Docstring?

    ในตัวอย่าง bmi_cal() เราจะเห็นว่า weight และ height มีได้หลายค่า ขึ้นอยู่กับหน่วยวัดที่ใช้ เช่น:

    • height: metre = 1.8; feet = 5.9
    • weight: kg = 80; pound = 176

    ถ้าเราใส่ค่าไม่ถูกต้องลงใน function เราจะได้ผลลัพธ์ที่ผิดกลับมา เช่น ใส่ height เป็น cm:

    # Using incorrect input
    wrong_bmi = calculate_bmi(weight=80, height=180)
    
    # Print the result
    print(wrong_bmi)
    

    ผลลัพธ์:

    0.0
    

    .

    🥸 What Is Docstring?

    เราสามารถแก้ปัญหานี้ได้ 2 วิธี:

    1. ตั้งชื่อ arguments ให้เรารู้ว่า ต้องใส่อะไรใน function (เช่น height_in_m, weight_in_kg)
    2. ใส่ docstring หรือ string ที่เก็บวิธีใช้ function ไว้

    เราสามารถเพิ่ม docstring ใน function ได้แบบนี้:

    # Adding docstring to the function
    def calculate_bmi(height, weight):
    
        # Docstring
        """
        Calculate BMI using weight and height:
        - Weight: kg
        - Height: m
    
        Return BMI rounded to 2 decimals.
        """
    
        # Calculate BMI
        bmi = weight / (height ** 2)
    
        # Round to 2 decimals
        bmi_rounded = round(bmi, 2)
    
        # Return BMI
        return bmi_rounded
    

    Pro tip: เราควรใส่ docstring ไว้ใน function โดยเฉพาะใน code ที่ใช้งานร่วมกับคนอื่น เพื่อให้คนอื่นเข้าใจการทำงาน function ของเรา

    .

    😎 Reading Docstring

    เราสามารถอ่าน docstring ได้ 2 วิธี:

    วิธีที่ 1. ใช้ help():

    # Read docstring with help()
    help(calculate_bmi)
    

    ผลลัพธ์:

    Help on function calculate_bmi in module __main__:
    
    calculate_bmi(height, weight)
        Calculate BMI using weight and height:
        - Weight: kg
        - Height: m
    
        Return BMI rounded to 2 decimals.
    

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

    # Read docstring with .__doc__:
    print(calculate_bmi.__doc__)
    

    ผลลัพธ์:

    Calculate BMI using weight and height:
        - Weight: kg
        - Height: m
    
        Return BMI rounded to 2 decimals.
    

    💬 Arguments

    เรามาดูการกำหนด 2 ประเภท arguments ใน functions กัน:

    1. Default arguments
    2. Arbitrary arguments

    .

    🫡 Default Arguments

    Default arguments เป็นค่าที่ function จะเรียกใช้ถ้าเราไม่กำหนด arguments เอง

    ยกตัวอย่างเช่น สร้าง function สำหรับคิดเลขยกกำลัง ซึ่งจะยกกำลัง 2 โดย default:

    # Create a function with default arguments
    def calculate_power(number, power=2):
    
        # Calculate number to the power of power
        result = number ** power
    
        # Return result
        return result
    
    # Call the function without power
    print(calculate_power(10))
    

    ผลลัพธ์:

    100
    

    แต่ถ้าเรากำหนด power เอง:

    # Call the function with power
    print(calculate_power(10, 3))
    

    ผลลัพธ์จะเปลี่ยนไป:

    1000
    

    .

    😶‍🌫️ Arbitrary Arguments

    Arbitrary arguments เป็นประเภท argument ที่เรากำหนดในกรณีที่เราไม่รู้ว่า จะมีกี่ arguments

    เราสามารถสร้าง function ที่รับ arguments แบบไม่ระบุจำนวนได้ 2 วิธี:

    1. *args: มี positional arguments (arguments ที่ใส่ตามลำดับ) แบบไม่ระบุจำนวน
    2. **kargs: มี keyword arguments (arguments ที่ใส่ตาม keywords) แบบไม่ระบุจำนวน

    ยกตัวอย่าง *args เช่น สร้าง function สำหรับคำนวณราคาสินค้าในตระกร้า ซึ่งเราไม่รู้ว่า จะมีสินค้ากี่ชิ้น:

    # Create a function calculate total price
    def calculate_total_price(*prices):
    
        # Calculate sum
        total = sum(prices)
    
        # Return total
        return total
    
    # Examples
    total_basket_01 = calculate_total_price(500, 1000)
    total_basket_02 = calculate_total_price(100, 200, 300)
    
    print(f"Basket 1: {total_basket_01}")
    print(f"Basket 2: {total_basket_02}")
    

    ผลลัพธ์:

    Basket 1: 1500
    Basket 2: 600
    

    ยกตัวอย่าง **kargs เช่น สร้าง function เก็บข้อมูล user ซึ่งแต่ละ user มีข้อมูลไม่เท่ากัน:

    # Create a function to return user's data
    def user_profile(**user_data):
        return user_data
    
    # Examples
    print(f"User 1: {user_profile(name='John')}")
    print(f"User 2: {user_profile(name='Jane', gender='F', age=20)}")
    

    ผลลัพธ์:

    User 1: {'name': 'John'}
    User 2: {'name': 'Jane', 'gender': 'F', 'age': 20}
    

    Note:

    • Arguments ใน *args จะถูกเก็บรวมในรูปของ tuple
    • Arguments ใน **kargs จะถูกเก็บรวมในรูปของ dictionary

    🛋️ lambda

    lambda เป็นการสร้าง function แบบไม่ระบุชื่อ โดยเราเขียนได้ดังนี้:

    lambda arguments: expression

    lambda มักใช้สร้าง function ขนาดเล็ก เช่น function หาผลรวม:

    # Create a function using lambda
    addition = lambda a, b: a + b
    
    # Call addition
    print(addition(1, 1))
    

    ผลลัพธ์:

    2
    

    จะเห็นได้ว่า lambda ในตัวอย่างมีค่าเท่ากับการใช้ def แบบนี้:

    # Same as lambda
    def addition(a, b):
        return a + b
    

    เมื่อเทียบกับ def จะเห็นว่า lambda มีการเขียนที่สั้นและง่ายกว่า

    เรามักใช้ lambda ในกรณีที่ต้องการสร้าง function อย่างง่ายและรวดเร็ว

    และเรามักใช้ def ในกรณีที่:

    • สร้าง function ที่มีความซับซ้อน (มีการทำงานหลายขั้นตอน)
    • สร้าง function สำหรับใช้งานร่วมกับคนอื่น เพราะ def จะทำให้คนอื่นอ่าน code ได้ง่ายกว่า

    😺 GitHub

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


    📃 References

  • dbplyr: แนะนำ package และ 6 ขั้นตอนในการทำงานกับ database ด้วย dplyr syntax ในภาษา R — ตัวอย่างการทำงานกับ Chinook database

    dbplyr: แนะนำ package และ 6 ขั้นตอนในการทำงานกับ database ด้วย dplyr syntax ในภาษา R — ตัวอย่างการทำงานกับ Chinook database

    ในบทความนี้ เราจะไปดูวิธีใช้ dbplyr ซึ่งเป็น package สำหรับทำงานกับ database ในภาษา R และเหมาะกับคนที่ต้องการทำงานโดยใช้ภาษา R เป็นหลักกัน

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


    1. 🤔 What Is dbplyr?
    2. 🏁 Getting Started
    3. 🏃‍♂️‍➡️ Using dbplyr
      1. 1️⃣ Connect to the Database
      2. 2️⃣ Create a Lazy Tibble
      3. 3️⃣ Create a Query
      4. 4️⃣ Show the Query
      5. 5️⃣ Collect the Result
      6. 6️⃣ Disconnect the Database
    4. 💪 Summary
    5. 😺 GitHub
    6. 📃 References
    7. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    🤔 What Is dbplyr?

    dbplyr เป็น package ในภาษา R สำหรับทำงานกับ database โดยใช้ dplyr syntax แทน SQL เช่น แทนที่เราเขียน:

    SELECT * FROM table
    

    เราสามารถใช้ dplyr syntax ได้แบบนี้:

    select(table, everything())
    

    (Note: อ่านวิธีใช้ dplyr ได้ที่นี่)


    🏁 Getting Started

    เราสามารถเริ่มใช้งาน dbplyr ได้โดยติดตั้งและโหลด 4 packages ดังนี้:

    1. DBI: สำหรับเชื่อมต่อกับ database (อ่านวิธีใช้เพิ่มเติมได้ที่นี่)
    2. RSQLite: สำหรับเชื่อมต่อกับ SQLite database (เราจะเปลี่ยน package นี้ตาม database ที่เราใช้ เช่น RPostgres สำหรับ Postgres database)
    3. dplyr: สำหรับ dplyr syntax เช่น select(), filter(), arrange()
    4. dbplyr: สำหรับทำงานกับ database ด้วย dplyr syntax
    # Install packages
    install.packages("DBI")
    install.packages("RSQLite")
    install.packages("dplyr")
    install.packages("dbplyr")
    
    # Load packages
    library(DBI)
    library(RSQLite)
    library(dplyr)
    library(dbplyr)
    

    🏃‍♂️‍➡️ Using dbplyr

    เราสามารถใช้ dbplyr เพื่อทำงานกับ database ได้ใน 6 ขั้นตอน:

    1. Connect to the database
    2. Create a lazy tibble
    3. Create a query
    4. Show the query
    5. Get the result

    .

    1️⃣ Connect to the Database

    ในขั้นแรก เราจะเชื่อมต่อกับ local database ด้วย DBI::dbConnect และ RSQLite::SQLite():

    # Connect to database
    con <- dbConnect(RSQLite::SQLite(),
                     "chinook.sqlite")
    

    Note: โหลด “chinook.sqlite” ได้จาก GitHub

    .

    2️⃣ Create a Lazy Tibble

    ในขั้นที่ 2 เราจะสร้าง lazy tibble หรือ object ที่ใช้แทน database table ซึ่งทำได้ใน 2 steps:

    Step 1. ดูรายชื่อ table ทั้งหมด ใน database ด้วย DBI::dbListTables():

    # View all tables
    dbListTables(con)
    

    ผลลัพธ์:

     [1] "Album"         "Artist"        "Customer"      "Employee"     
     [5] "Genre"         "Invoice"       "InvoiceLine"   "MediaType"    
     [9] "Playlist"      "PlaylistTrack" "Track" 
    

    Step 2. สร้าง lazy tibble จากชื่อ table ที่ต้องการ ด้วย dplyr::tbl():

    # Create lazy tibble
    tracks <- tbl(con,
                  "Track")
    
    # View tibble
    tracks
    

    ผลลัพธ์:

    # Source:   table<`Track`> [?? x 9]
    # Database: sqlite 3.50.1 [C:\\My Code\\RStudio\\chinook.sqlite]
       TrackId Name           AlbumId MediaTypeId GenreId Composer Milliseconds  Bytes UnitPrice
         <int> <chr>            <int>       <int>   <int> <chr>           <int>  <int>     <dbl>
     1       1 For Those Abo…       1           1       1 Angus Y…       343719 1.12e7      0.99
     2       2 Balls to the …       2           2       1 NA             342562 5.51e6      0.99
     3       3 Fast As a Sha…       3           2       1 F. Balt…       230619 3.99e6      0.99
     4       4 Restless and …       3           2       1 F. Balt…       252051 4.33e6      0.99
     5       5 Princess of t…       3           2       1 Deaffy …       375418 6.29e6      0.99
     6       6 Put The Finge…       1           1       1 Angus Y…       205662 6.71e6      0.99
     7       7 Let's Get It …       1           1       1 Angus Y…       233926 7.64e6      0.99
     8       8 Inject The Ve…       1           1       1 Angus Y…       210834 6.85e6      0.99
     9       9 Snowballed           1           1       1 Angus Y…       203102 6.60e6      0.99
    10      10 Evil Walks           1           1       1 Angus Y…       263497 8.61e6      0.99
    # ℹ more rows
    # ℹ Use `print(n = ...)` to see more rows
    

    .

    3️⃣ Create a Query

    ในขั้นที่ 3 เราจะเขียน dplyr syntax เพื่อ query table ที่ต้องการ

    เช่น สรุปข้อมูลจำนวนเพลง ค่าเฉลี่ยความยาวเพลง (Milliseconds) และขนาดเพลง (Bytes) ของแต่ละ album:

    # Create query
    album_info <- tracks |>
      
      # Group by album
      group_by(AlbumId) |>
      
      # Summarise
      summarise(
        
        # Number of tracks
        tracks = n(),
        
        # Average duration
        mean_millisec = mean(Milliseconds,
                             na.rm = TRUE),
        
        # Total size
        total_bytes = sum(Bytes)
      ) |>
      
      # Sort by duration
      arrange(desc(mean_millisec))
    

    ตอนนี้ code ของเราจะยังไม่ถูกส่งไปยัง database เพราะ lazy tibble จะเก็บคำสั่งไว้จนกว่าเราจะมีคำสั่งให้ส่ง

    เราไปดูคำสั่งที่เราสามารถใช้กับ code ที่ยังไม่ถูกส่งไปกัน

    .

    4️⃣ Show the Query

    เราสามารถใช้ dbplyr::show_query() เพื่อดู SQL ที่จะถูกส่งไปยัง database (ซึ่งแปลงมาจาก dplyr syntax ของเรา) ได้:

    # Show query
    show_query(album_info)
    

    ผลลัพธ์:

    <SQL>
    SELECT
      `AlbumId`,
      COUNT(*) AS `tracks`,
      AVG(`Milliseconds`) AS `mean_millisec`,
      SUM(`Bytes`) AS `total_bytes`
    FROM `Track`
    GROUP BY `AlbumId`
    ORDER BY `mean_millisec` DESC
    

    .

    5️⃣ Collect the Result

    เราสามารถส่ง code เพื่อไป query database ได้ด้วย dbplyr::collect():

    # Get result
    album_info_tb <- collect(album_info)
    
    # View the result
    album_info_tb
    

    ผลลัพธ์:

    # A tibble: 347 × 4
       AlbumId tracks mean_millisec total_bytes
         <int>  <int>         <dbl>     <int64>
     1     253     24      2925574. 12872621850
     2     227     19      2778265. 10059916535
     3     229     26      2717907  13917603291
     4     231     24      2637068. 12344960921
     5     226      1      2622250    490750393
     6     228     23      2599142. 11781321607
     7     230     25      2594197.  5280909854
     8     254      1      2484567    492670102
     9     261     17      2321673.  7708725642
    10     251     25      1532684.  7652731262
    # ℹ 337 more rows
    # ℹ Use `print(n = ...)` to see more rows
    

    .

    6️⃣ Disconnect the Database

    สุดท้าย เมื่อเราทำงานเสร็จแล้ว เราจะปิดการเชื่อมต่อกับ database ด้วย DBI::dbDisconnect():

    # Disconnect from database
    dbDisconnect(con)
    

    เป็นการจบ loop การทำงานกับ database ด้วย dbplyr


    💪 Summary

    ในบทความนี้ เราได้ไปทำความรู้จัก 6 ขั้นตอนในการใช้ dbplyr เพื่อทำงานกับ database ในภาษา R กัน:

    1. Connect to the database: DBI::dbConnect() และ RSQLite::SQLite()
    2. Create a lazy tibble: dplyr::tbl()
    3. Create a query: ใช้ dplyr syntax คู่กับ lazy tibble
    4. Show the query: dbplyr::show_query()
    5. Collect the result: dbplyr::collect()
    6. Disconnect the database: DBI::dbDisconnect()

    😺 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:

  • DBI: แนะนำ 4 ขั้นตอนในการเชื่อมต่อและ query ข้อมูลจาก database โดยใช้ภาษา R — ตัวอย่างการทำงานกับ Chinook database

    DBI: แนะนำ 4 ขั้นตอนในการเชื่อมต่อและ query ข้อมูลจาก database โดยใช้ภาษา R — ตัวอย่างการทำงานกับ Chinook database

    ในบทความนี้ เราจะมาดู 4 ขั้นตอนในการเชื่อมต่อและทำงานกับ database ในภาษา R ด้วย DBI package กัน:

    1. Get started
    2. Explore the database
    3. Query the database
    4. Close the connection

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


    1. 💻 Step 1. Get Started
      1. 📦 DBI Package
      2. ⬇️ Install & Connect
    2. 👀 Step 2. Explore the Database
      1. 1️⃣ dbListTable()
      2. 2️⃣ dbGetQuery()
    3. 🔍 Step 3. Query the Database
      1. 1️⃣ dbReadTable()
      2. 2️⃣ dbGetQuery()
      3. 3️⃣ dbSendQuery()
    4. 🤚 Step 4. Close the Connection
    5. 💪 Summary
    6. 😺 GitHub
    7. 📃 References
    8. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    💻 Step 1. Get Started

    📦 DBI Package

    DBI (Database Interface) เป็น package สำหรับเชื่อมต่อกับ database ซึ่งทำให้เราทำงานกับ database ในภาษา R ได้โดยตรง

    ในบทความนี้ เรามาลองดูการใช้งาน DBI ผ่านการทำงานกับ Chinook SQLite database กัน (เราสามารถโหลด Chinook เพื่อลองทำตามได้จาก GitHub)

    .

    ⬇️ Install & Connect

    ในขั้นแรกของการใช้งาน เราจะติดตั้งและโหลด DBI พร้อมกับ package สำหรับ database ที่เราจะทำงานด้วย

    อย่างในกรณีนี้ เราจะติดตั้งและโหลด RSQLite package เพราะเราจะทำงานกับ SQLite database

    Note: ถ้าเราทำงานกับ database อื่น เราจะต้องติดตั้งและโหลด package อื่น เช่น:

    • MySQL → RMySQL
    • PostgresSQL → RPostgresSQL
    • Oracle → ROracle

    ติดตั้ง packages:

    # Install
    install.packages("DBI")
    install.packages("RSQLite")
    

    โหลด packages:

    # Load
    library(DBI)
    library(RSQLite)
    

    หลังติดตั้งและโหลด packages แล้ว เราจะเชื่อมต่อกับ database ด้วย dbConnect() แบบนี้:

    # Connect to database
    con <- dbConnect(RSQLite::SQLite(),
                     "chinook.sqlite")
    

    Note: ในกรณีที่ database ไม่ได้อยู่ใน working directory เราจะต้องใช้ absolute file path แทนชื่อไฟล์ เช่น:

    # Connect to database
    con <- dbConnect(RSQLite::SQLite(),
                     "C:/Users/YourUser/Documents/R_Projects/my_data/chinook.sqlite")
    

    เท่านี้ เราก็พร้อมที่จะทำงานกับ database กันแล้ว


    👀 Step 2. Explore the Database

    เริ่มแรก เราจะสำรวจ database เพื่อทำความเข้าใจโครงสร้างข้อมูลกันก่อน

    เรามี 2 functions ที่ช่วยเราได้ ได้แก่:

    1. dbListTables(): ดูรายชื่อ tables ทั้งหมดใน database
    2. dbGetQuety(): ดู columns ใน table ที่ต้องการ

    .

    1️⃣ dbListTable()

    ตัวอย่าง:

    # List tables in the database
    dbListTables(con)
    

    ผลลัพธ์:

     [1] "Album"         "Artist"        "Customer"      "Employee"     
     [5] "Genre"         "Invoice"       "InvoiceLine"   "MediaType"    
     [9] "Playlist"      "PlaylistTrack" "Track"  
    

    .

    2️⃣ dbGetQuery()

    ตัวอย่าง:

    # List columns in a table
    dbGetQuery(con,
               "PRAGMA table_info(Artist)")
    

    ผลลัพธ์:

      cid     name          type notnull dflt_value pk
    1   0 ArtistId       INTEGER       1         NA  1
    2   1     Name NVARCHAR(120)       0         NA  0
    

    ในกรณีที่เราต้องการดู columns ในทุก table เราสามารถใช้ for loop ช่วยได้แบบนี้:

    # Get the table list
    tables <- dbListTables(con)
    
    # Get all columns
    for (table_name in tables) {
      
      # Print the table name
      message(paste0("\\n👉 Table: ", table_name))
      
      # Get the columns
      column_info <- dbGetQuery(con,
                                paste0("PRAGMA table_info(",
                                       table_name, 
                                       ")"))
      
      # Print the columns
      print(column_info)
    }
    

    ผลลัพธ์:

    👉 Table: Album
      cid     name          type notnull dflt_value pk
    1   0  AlbumId       INTEGER       1         NA  1
    2   1    Title NVARCHAR(160)       1         NA  0
    3   2 ArtistId       INTEGER       1         NA  0
    👉 Table: Artist
      cid     name          type notnull dflt_value pk
    1   0 ArtistId       INTEGER       1         NA  1
    2   1     Name NVARCHAR(120)       0         NA  0
    👉 Table: Customer
       cid         name         type notnull dflt_value pk
    1    0   CustomerId      INTEGER       1         NA  1
    2    1    FirstName NVARCHAR(40)       1         NA  0
    3    2     LastName NVARCHAR(20)       1         NA  0
    4    3      Company NVARCHAR(80)       0         NA  0
    5    4      Address NVARCHAR(70)       0         NA  0
    6    5         City NVARCHAR(40)       0         NA  0
    7    6        State NVARCHAR(40)       0         NA  0
    8    7      Country NVARCHAR(40)       0         NA  0
    9    8   PostalCode NVARCHAR(10)       0         NA  0
    10   9        Phone NVARCHAR(24)       0         NA  0
    11  10          Fax NVARCHAR(24)       0         NA  0
    12  11        Email NVARCHAR(60)       1         NA  0
    13  12 SupportRepId      INTEGER       0         NA  0
    👉 Table: Employee
       cid       name         type notnull dflt_value pk
    1    0 EmployeeId      INTEGER       1         NA  1
    2    1   LastName NVARCHAR(20)       1         NA  0
    3    2  FirstName NVARCHAR(20)       1         NA  0
    4    3      Title NVARCHAR(30)       0         NA  0
    5    4  ReportsTo      INTEGER       0         NA  0
    6    5  BirthDate     DATETIME       0         NA  0
    7    6   HireDate     DATETIME       0         NA  0
    8    7    Address NVARCHAR(70)       0         NA  0
    9    8       City NVARCHAR(40)       0         NA  0
    10   9      State NVARCHAR(40)       0         NA  0
    11  10    Country NVARCHAR(40)       0         NA  0
    12  11 PostalCode NVARCHAR(10)       0         NA  0
    13  12      Phone NVARCHAR(24)       0         NA  0
    14  13        Fax NVARCHAR(24)       0         NA  0
    15  14      Email NVARCHAR(60)       0         NA  0
    👉 Table: Genre
      cid    name          type notnull dflt_value pk
    1   0 GenreId       INTEGER       1         NA  1
    2   1    Name NVARCHAR(120)       0         NA  0
    👉 Table: Invoice
      cid              name          type notnull dflt_value pk
    1   0         InvoiceId       INTEGER       1         NA  1
    2   1        CustomerId       INTEGER       1         NA  0
    3   2       InvoiceDate      DATETIME       1         NA  0
    4   3    BillingAddress  NVARCHAR(70)       0         NA  0
    5   4       BillingCity  NVARCHAR(40)       0         NA  0
    6   5      BillingState  NVARCHAR(40)       0         NA  0
    7   6    BillingCountry  NVARCHAR(40)       0         NA  0
    8   7 BillingPostalCode  NVARCHAR(10)       0         NA  0
    9   8             Total NUMERIC(10,2)       1         NA  0
    👉 Table: InvoiceLine
      cid          name          type notnull dflt_value pk
    1   0 InvoiceLineId       INTEGER       1         NA  1
    2   1     InvoiceId       INTEGER       1         NA  0
    3   2       TrackId       INTEGER       1         NA  0
    4   3     UnitPrice NUMERIC(10,2)       1         NA  0
    5   4      Quantity       INTEGER       1         NA  0
    👉 Table: MediaType
      cid        name          type notnull dflt_value pk
    1   0 MediaTypeId       INTEGER       1         NA  1
    2   1        Name NVARCHAR(120)       0         NA  0
    👉 Table: Playlist
      cid       name          type notnull dflt_value pk
    1   0 PlaylistId       INTEGER       1         NA  1
    2   1       Name NVARCHAR(120)       0         NA  0
    👉 Table: PlaylistTrack
      cid       name    type notnull dflt_value pk
    1   0 PlaylistId INTEGER       1         NA  1
    2   1    TrackId INTEGER       1         NA  2
    👉 Table: Track
      cid         name          type notnull dflt_value pk
    1   0      TrackId       INTEGER       1         NA  1
    2   1         Name NVARCHAR(200)       1         NA  0
    3   2      AlbumId       INTEGER       0         NA  0
    4   3  MediaTypeId       INTEGER       1         NA  0
    5   4      GenreId       INTEGER       0         NA  0
    6   5     Composer NVARCHAR(220)       0         NA  0
    7   6 Milliseconds       INTEGER       1         NA  0
    8   7        Bytes       INTEGER       0         NA  0
    9   8    UnitPrice NUMERIC(10,2)       1         NA  0
    

    🔍 Step 3. Query the Database

    หลังสำรวจ database แล้ว เราสามารถ query ข้อมูลได้ด้วย 3 functions ได้แก่:

    1. dbReadTable()
    2. dbGetQuery()
    3. dbSendQuery()

    .

    1️⃣ dbReadTable()

    เราจะใช้ dbReadTable() เมื่อต้องการดึงข้อมูลทั้งหมดมาจาก table ที่ต้องการ

    ตัวอย่างเช่น ดูข้อมูลทั้งหมดใน Genre:

    # Query with dbReadTable()
    dbReadTable(con,
                "Genre")
    

    ผลลัพธ์:

       GenreId               Name
    1        1               Rock
    2        2               Jazz
    3        3              Metal
    4        4 Alternative & Punk
    5        5      Rock And Roll
    6        6              Blues
    7        7              Latin
    8        8             Reggae
    9        9                Pop
    10      10         Soundtrack
    11      11         Bossa Nova
    12      12     Easy Listening
    13      13        Heavy Metal
    14      14           R&B/Soul
    15      15  Electronica/Dance
    16      16              World
    17      17        Hip Hop/Rap
    18      18    Science Fiction
    19      19           TV Shows
    20      20   Sci Fi & Fantasy
    21      21              Drama
    22      22             Comedy
    23      23        Alternative
    24      24          Classical
    25      25              Opera
    

    .

    2️⃣ dbGetQuery()

    ในกรณีที่เราต้องการดูข้อมูลแบบเจาะจง เราจะใช้ dbGetQuery() ซึ่งต้องการ 2 arguments:

    1. Connection ที่เชื่อมต่อกับ database
    2. SQL query ที่กำหนดข้อมูลที่ต้องการจาก database

    ตัวอย่างการใช้งาน #1 – ดึงข้อมูลลูกค้าที่มาจากบราซิล:

    # Query with dbGetQuery() - example 1
    dbGetQuery(con,
               "SELECT
                  CustomerId,
                  FirstName,
                  LastName, Email
                FROM
                  Customer
                WHERE
                  country = 'Brazil';")
    

    ผลลัพธ์:

      CustomerId FirstName  LastName                         Email
    1          1      Luís Gonçalves          luisg@embraer.com.br
    2         10   Eduardo   Martins      eduardo@woodstock.com.br
    3         11 Alexandre     Rocha              alero@uol.com.br
    4         12   Roberto   Almeida roberto.almeida@riotur.gov.br
    5         13  Fernanda     Ramos      fernadaramos4@uol.com.br
    

    ตัวอย่าง #2 – คำนวณยอดขายรวมของแต่ละประเทศ โดยเรียงจากมากไปน้อย:

    # Query with dbGetQuery() - example 2
    dbGetQuery(con,
               "SELECT
                  BillingCountry,
                  SUM(Total) AS TotalSales
                FROM
                  Invoice
                GROUP BY
                  BillingCountry
                ORDER BY
                  TotalSales DESC;")
    

    ผลลัพธ์:

       BillingCountry TotalSales
    1             USA     523.06
    2          Canada     303.96
    3          France     195.10
    4          Brazil     190.10
    5         Germany     156.48
    6  United Kingdom     112.86
    7  Czech Republic      90.24
    8        Portugal      77.24
    9           India      75.26
    10          Chile      46.62
    11        Ireland      45.62
    12        Hungary      45.62
    13        Austria      42.62
    14        Finland      41.62
    15    Netherlands      40.62
    16         Norway      39.62
    17         Sweden      38.62
    18          Spain      37.62
    19         Poland      37.62
    20          Italy      37.62
    21        Denmark      37.62
    22        Belgium      37.62
    23      Australia      37.62
    24      Argentina      37.62
    

    ตัวอย่าง #3 – ดึงชื่อเพลงและชื่ออัลบัม 10 อันดับแรก:

    # Query with dbGetQuery() - example 3
    dbGetQuery(con,
               "SELECT
                  T.Name AS TrackName,
                  A.Title AS AlbumTitle
                FROM
                  Track AS T
                JOIN
                  Album AS A ON T.AlbumID = A.AlbumID
                LIMIT 10;")
    

    ผลลัพธ์:

                                     TrackName                            AlbumTitle
    1  For Those About To Rock (We Salute You) For Those About To Rock We Salute You
    2                        Balls to the Wall                     Balls to the Wall
    3                          Fast As a Shark                     Restless and Wild
    4                        Restless and Wild                     Restless and Wild
    5                     Princess of the Dawn                     Restless and Wild
    6                    Put The Finger On You For Those About To Rock We Salute You
    7                          Let's Get It Up For Those About To Rock We Salute You
    8                         Inject The Venom For Those About To Rock We Salute You
    9                               Snowballed For Those About To Rock We Salute You
    10                              Evil Walks For Those About To Rock We Salute You
    

    .

    3️⃣ dbSendQuery()

    dbSendQuery() ทำงานเหมือนกับ dbGetQuery() แต่ต่างกันที่ dbGetQuery() จะยังส่งข้อมูลใด ๆ กลับมาจนกว่าเราจะเรียกดูด้วย dbFetch()

    ยกตัวอย่างเช่น ดูข้อมูลลูกค้า 10 รายชื่อแรกเมื่อเรียงตามนามสกุล:

    # Send query
    res <- dbSendQuery(con,
                       "SELECT
                          CustomerId,
                          LastName,
                          FirstName,
                          Email
                        FROM
                          Customer
                        ORDER BY
                          LastName
                        LIMIT 10;")
    
    # Fetch results
    dbFetch(res)
    

    ผลลัพธ์:

       CustomerId   LastName FirstName                         Email
    1          12    Almeida   Roberto roberto.almeida@riotur.gov.br
    2          28    Barnett     Julia           jubarnett@gmail.com
    3          39    Bernard   Camille      camille.bernard@yahoo.fr
    4          18     Brooks  Michelle             michelleb@aol.com
    5          29      Brown    Robert              robbrown@shaw.ca
    6          21      Chase     Kathy           kachase@hotmail.com
    7          26 Cunningham   Richard      ricunningham@hotmail.com
    8          41     Dubois      Marc       marc.dubois@hotmail.com
    9          34  Fernandes      João           jfernandes@yahoo.pt
    10         30    Francis    Edward           edfrancis@yachoo.ca
    

    เมื่อเราเรียกดูข้อมูลทั้งหมดแล้ว เราจะไม่สามารถเรียกดูซ้ำได้:

    # Fetch results
    dbFetch(res)
    

    ผลลัพธ์:

    > dbFetch(res)
    [1] CustomerId LastName   FirstName  Email     
    <0 rows> (or 0-length row.names)
    

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

    # Send query
    res <- dbSendQuery(con,
                       "SELECT
                          CustomerId,
                          LastName,
                          FirstName,
                          Email
                        FROM
                          Customer
                        ORDER BY
                          LastName
                        LIMIT 10;")
    
    # Fetch five, twice
    dbFetch(res, n = 5)
    dbFetch(res, n = 5)
    dbFetch(res, n = 5)
    

    ผลลัพธ์:

    > dbFetch(res, n = 5)
      CustomerId LastName FirstName                         Email
    1         12  Almeida   Roberto roberto.almeida@riotur.gov.br
    2         28  Barnett     Julia           jubarnett@gmail.com
    3         39  Bernard   Camille      camille.bernard@yahoo.fr
    4         18   Brooks  Michelle             michelleb@aol.com
    5         29    Brown    Robert              robbrown@shaw.ca
    > dbFetch(res, n = 5)
      CustomerId   LastName FirstName                    Email
    1         21      Chase     Kathy      kachase@hotmail.com
    2         26 Cunningham   Richard ricunningham@hotmail.com
    3         41     Dubois      Marc  marc.dubois@hotmail.com
    4         34  Fernandes      João      jfernandes@yahoo.pt
    5         30    Francis    Edward      edfrancis@yachoo.ca
    > dbFetch(res, n = 5)
    [1] CustomerId LastName   FirstName  Email     
    <0 rows> (or 0-length row.names)
    

    เราสามารถใช้ dbSendQuery() และ dbFetch() เพื่อดูข้อมูลเป็นชุด ๆ แทนที่จะดูข้อมูลทั้งหมดในครั้งเดียวแบบ dbGetQuery()

    Note: ในกรณีที่เราต้องการลบ query ที่เราส่งไป database ด้วย dbSendQuery() ให้เราใช้ dbClearResult():

    # Clear results
    dbClearResult(res)
    

    🤚 Step 4. Close the Connection

    สุดท้าย เมื่อเราทำงานกับ database เสร็จแล้ว เราต้องสิ้นสุดการเชื่อมต่อกับ database ด้วย dbDisconnect():

    # Close the connection
    dbDisconnect(con)
    

    เป็นอันจบการทำงานกับ database ด้วย DBI


    💪 Summary

    ในบทความนี้ เราได้ไปดูวิธีการใช้งาน DBI เพื่อทำงานกับ database กัน:

    เชื่อมต่อ database:

    • dbConnect()

    สำรวจ database:

    • dbListTables()
    • dbGetQuery()

    Query ข้อมูล:

    • dbReadTable()
    • dbGetQuery()
    • dbSendQuery(), dbFetch(), และ dbClearResult()

    ปิดการเชื่อมต่อ:

    • dbDisconnect()

    😺 GitHub

    ดู code และ database ในบทความนี้ได้ที่ 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:

  • sqldf(): แนะนำ function ในการทำงานกับ data frame ด้วย SQL ในภาษา R — ตัวอย่างจาก Cars93

    sqldf(): แนะนำ function ในการทำงานกับ data frame ด้วย SQL ในภาษา R — ตัวอย่างจาก Cars93

    ในบทความนี้ เราจะมาดูวิธีใช้ sqldf() ซึ่งเป็น function ที่ช่วยให้เราทำงานกับ data frame ในภาษา R ได้ด้วย SQL syntax และเหมาะกับคนที่คุ้นเคยกับการใช้ SQL ในการทำงานกัน

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


    1. 🏁 Getting Started: Install & Load sqldf
    2. 🏃‍♂️‍➡️ Using sqldf
      1. 1️⃣ Example 1. SELECT
      2. 2️⃣ Example 2. WHERE
      3. 3️⃣ Example 3. Aggregate
    3. 😺 GitHub
    4. 📃 References
    5. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    🏁 Getting Started: Install & Load sqldf

    ก่อนเริ่มใช้ sqldf() เราจะต้องติดตั้งและโหลด sqldf ซึ่งเป็น package ต้นทางของ sdldf() ด้วย install.packages() และ library() ตามลำดับ:

    # Install sqldf
    install.packages("sqldf")
    
    # Load sqldf
    library(sqldf)
    

    Note:

    • เราใช้ install.packages() เพื่อติดตั้งแค่ครั้งเดียว
    • เราใช้ library() เพื่อโหลด sqldf ทุกครั้งที่เริ่ม session ใหม่

    🏃‍♂️‍➡️ Using sqldf

    sqldf() ต้องการ 1 argument คือ character ที่มี SQL query เช่น:

    sqldf("SELECT * FROM df")
    

    เราลองมาดูตัวอย่างการใช้ sqldf() กับ Cars93 dataset (จาก MASS package) ซึ่งมีข้อมูลรถ 93 คันที่ขายในปี ค.ศ. 1993:

    # Install MASS
    install.packages("MASS")
    
    # Load MASS
    library(MASS)
    
    # Load the dataset
    data(Cars93)
    
    # View the dataset structure
    str(Cars93)
    

    ผลลัพธ์:

    'data.frame':	93 obs. of  27 variables:
     $ Manufacturer      : Factor w/ 32 levels "Acura","Audi",..: 1 1 2 2 3 4 4 4 4 5 ...
     $ Model             : Factor w/ 93 levels "100","190E","240",..: 49 56 9 1 6 24 54 74 73 35 ...
     $ Type              : Factor w/ 6 levels "Compact","Large",..: 4 3 1 3 3 3 2 2 3 2 ...
     $ Min.Price         : num  12.9 29.2 25.9 30.8 23.7 14.2 19.9 22.6 26.3 33 ...
     $ Price             : num  15.9 33.9 29.1 37.7 30 15.7 20.8 23.7 26.3 34.7 ...
     $ Max.Price         : num  18.8 38.7 32.3 44.6 36.2 17.3 21.7 24.9 26.3 36.3 ...
     $ MPG.city          : int  25 18 20 19 22 22 19 16 19 16 ...
     $ MPG.highway       : int  31 25 26 26 30 31 28 25 27 25 ...
     $ AirBags           : Factor w/ 3 levels "Driver & Passenger",..: 3 1 2 1 2 2 2 2 2 2 ...
     $ DriveTrain        : Factor w/ 3 levels "4WD","Front",..: 2 2 2 2 3 2 2 3 2 2 ...
     $ Cylinders         : Factor w/ 6 levels "3","4","5","6",..: 2 4 4 4 2 2 4 4 4 5 ...
     $ EngineSize        : num  1.8 3.2 2.8 2.8 3.5 2.2 3.8 5.7 3.8 4.9 ...
     $ Horsepower        : int  140 200 172 172 208 110 170 180 170 200 ...
     $ RPM               : int  6300 5500 5500 5500 5700 5200 4800 4000 4800 4100 ...
     $ Rev.per.mile      : int  2890 2335 2280 2535 2545 2565 1570 1320 1690 1510 ...
     $ Man.trans.avail   : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 1 1 1 1 ...
     $ Fuel.tank.capacity: num  13.2 18 16.9 21.1 21.1 16.4 18 23 18.8 18 ...
     $ Passengers        : int  5 5 5 6 4 6 6 6 5 6 ...
     $ Length            : int  177 195 180 193 186 189 200 216 198 206 ...
     $ Wheelbase         : int  102 115 102 106 109 105 111 116 108 114 ...
     $ Width             : int  68 71 67 70 69 69 74 78 73 73 ...
     $ Turn.circle       : int  37 38 37 37 39 41 42 45 41 43 ...
     $ Rear.seat.room    : num  26.5 30 28 31 27 28 30.5 30.5 26.5 35 ...
     $ Luggage.room      : int  11 15 14 17 13 16 17 21 14 18 ...
     $ Weight            : int  2705 3560 3375 3405 3640 2880 3470 4105 3495 3620 ...
     $ Origin            : Factor w/ 2 levels "USA","non-USA": 2 2 2 2 2 1 1 1 1 1 ...
     $ Make              : Factor w/ 93 levels "Acura Integra",..: 1 2 4 3 5 6 7 9 8 10 ...
    

    .

    1️⃣ Example 1. SELECT

    เลือกข้อมูลจาก columns Manufacturer, Model, Min.Price, และ Max.Price:

    # Set query
    select_query <- "
    SELECT
      Manufacturer,
      Model,
      `Min.Price`,
      `Max.Price`
    FROM
      Cars93
    "
    
    # Select from df
    select_result <- sqldf(select_query)
    
    # View the result
    select_result
    

    Note: เราใช้ backticks (`) สำหรับชื่อ columns ที่ไม่ valid ใน SQL (เช่น column ที่มี . อย่าง Min.Price และ Max.Price)

    ผลลัพธ์:

        Manufacturer          Model Min.Price Max.Price
    1          Acura        Integra      12.9      18.8
    2          Acura         Legend      29.2      38.7
    3           Audi             90      25.9      32.3
    4           Audi            100      30.8      44.6
    5            BMW           535i      23.7      36.2
    6          Buick        Century      14.2      17.3
    7          Buick        LeSabre      19.9      21.7
    8          Buick     Roadmaster      22.6      24.9
    9          Buick        Riviera      26.3      26.3
    10      Cadillac        DeVille      33.0      36.3
    11      Cadillac        Seville      37.5      42.7
    12     Chevrolet       Cavalier       8.5      18.3
    13     Chevrolet        Corsica      11.4      11.4
    14     Chevrolet         Camaro      13.4      16.8
    15     Chevrolet         Lumina      13.4      18.4
    16     Chevrolet     Lumina_APV      14.7      18.0
    17     Chevrolet          Astro      14.7      18.6
    18     Chevrolet        Caprice      18.0      19.6
    19     Chevrolet       Corvette      34.6      41.5
    20      Chrylser       Concorde      18.4      18.4
    21      Chrysler        LeBaron      14.5      17.1
    22      Chrysler       Imperial      29.5      29.5
    23         Dodge           Colt       7.9      10.6
    24         Dodge         Shadow       8.4      14.2
    25         Dodge         Spirit      11.9      14.7
    26         Dodge        Caravan      13.6      24.4
    27         Dodge        Dynasty      14.8      16.4
    28         Dodge        Stealth      18.5      33.1
    29         Eagle         Summit       7.9      16.5
    30         Eagle         Vision      17.5      21.2
    31          Ford        Festiva       6.9       7.9
    32          Ford         Escort       8.4      11.9
    33          Ford          Tempo      10.4      12.2
    34          Ford        Mustang      10.8      21.0
    35          Ford          Probe      12.8      15.2
    36          Ford       Aerostar      14.5      25.3
    37          Ford         Taurus      15.6      24.8
    38          Ford Crown_Victoria      20.1      21.7
    39           Geo          Metro       6.7      10.0
    40           Geo          Storm      11.5      13.5
    41         Honda        Prelude      17.0      22.7
    42         Honda          Civic       8.4      15.8
    43         Honda         Accord      13.8      21.2
    44       Hyundai          Excel       6.8       9.2
    45       Hyundai        Elantra       9.0      11.0
    46       Hyundai         Scoupe       9.1      11.0
    47       Hyundai         Sonata      12.4      15.3
    48      Infiniti            Q45      45.4      50.4
    49         Lexus          ES300      27.5      28.4
    50         Lexus          SC300      34.7      35.6
    51       Lincoln    Continental      33.3      35.3
    52       Lincoln       Town_Car      34.4      37.8
    53         Mazda            323       7.4       9.1
    54         Mazda        Protege      10.9      12.3
    55         Mazda            626      14.3      18.7
    56         Mazda            MPV      16.6      21.7
    57         Mazda           RX-7      32.5      32.5
    58 Mercedes-Benz           190E      29.0      34.9
    59 Mercedes-Benz           300E      43.8      80.0
    60       Mercury          Capri      13.3      15.0
    61       Mercury         Cougar      14.9      14.9
    62    Mitsubishi         Mirage       7.7      12.9
    63    Mitsubishi       Diamante      22.4      29.9
    64        Nissan         Sentra       8.7      14.9
    65        Nissan         Altima      13.0      18.3
    66        Nissan          Quest      16.7      21.5
    67        Nissan         Maxima      21.0      22.0
    68    Oldsmobile        Achieva      13.0      14.0
    69    Oldsmobile  Cutlass_Ciera      14.2      18.4
    70    Oldsmobile     Silhouette      19.5      19.5
    71    Oldsmobile   Eighty-Eight      19.5      21.9
    72      Plymouth          Laser      11.4      17.4
    73       Pontiac         LeMans       8.2       9.9
    74       Pontiac        Sunbird       9.4      12.8
    75       Pontiac       Firebird      14.0      21.4
    76       Pontiac     Grand_Prix      15.4      21.6
    77       Pontiac     Bonneville      19.4      29.4
    78          Saab            900      20.3      37.1
    79        Saturn             SL       9.2      12.9
    80        Subaru          Justy       7.3       9.5
    81        Subaru         Loyale      10.5      11.3
    82        Subaru         Legacy      16.3      22.7
    83        Suzuki          Swift       7.3      10.0
    84        Toyota         Tercel       7.8      11.8
    85        Toyota         Celica      14.2      22.6
    86        Toyota          Camry      15.2      21.2
    87        Toyota         Previa      18.9      26.6
    88    Volkswagen            Fox       8.7       9.5
    89    Volkswagen        Eurovan      16.6      22.7
    90    Volkswagen         Passat      17.6      22.4
    91    Volkswagen        Corrado      22.9      23.7
    92         Volvo            240      21.8      23.5
    93         Volvo            850      24.8      28.5
    

    .

    2️⃣ Example 2. WHERE

    คัดกรองข้อมูลรถที่ชื่อผู้ผลิตขึ้นต้นด้วย “M”:

    # Set query
    where_result <- "
    SELECT
      Manufacturer,
      Model,
      `Min.Price`,
      `Max.Price`
    FROM
      Cars93
    WHERE
      Manufacturer LIKE 'M%'
    "
    
    # Filter df
    where_result <- sqldf(where_result)
    
    # View the result
    where_result
    

    ผลลัพธ์:

        Manufacturer    Model Min.Price Max.Price
    1          Mazda      323       7.4       9.1
    2          Mazda  Protege      10.9      12.3
    3          Mazda      626      14.3      18.7
    4          Mazda      MPV      16.6      21.7
    5          Mazda     RX-7      32.5      32.5
    6  Mercedes-Benz     190E      29.0      34.9
    7  Mercedes-Benz     300E      43.8      80.0
    8        Mercury    Capri      13.3      15.0
    9        Mercury   Cougar      14.9      14.9
    10    Mitsubishi   Mirage       7.7      12.9
    11    Mitsubishi Diamante      22.4      29.9
    

    .

    3️⃣ Example 3. Aggregate

    หารถ 10 อันดับแรกที่มีราคาสูงสุด:

    # Set query
    aggregate_query <- "
    SELECT
      Manufacturer,
      AVG(Price) AS Avg_Price
    FROM
      Cars93
    GROUP BY
      Manufacturer
    ORDER BY
      Avg_Price DESC
    LIMIT
      10;
    "
    
    # Aggregate df
    aggregate_result <- sqldf(aggregate_query)
    
    # View the result
    aggregate_result
    

    ผลลัพธ์:

        Manufacturer Avg_Price
    1       Infiniti      47.9
    2  Mercedes-Benz      46.9
    3       Cadillac      37.4
    4        Lincoln      35.2
    5           Audi      33.4
    6          Lexus      31.6
    7            BMW      30.0
    8           Saab      28.7
    9          Acura      24.9
    10         Volvo      24.7
    

    😺 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:

  • readxl และ XLConnect: วิธีใช้ 2 packages สำหรับทำงานกับ Excel ในภาษา R — ตัวอย่างการทำงานกับ Daily Household Transactions

    readxl และ XLConnect: วิธีใช้ 2 packages สำหรับทำงานกับ Excel ในภาษา R — ตัวอย่างการทำงานกับ Daily Household Transactions

    Excel เป็นเครื่องมือทำงานยอดนิยมในการทำงาน ซึ่งทำให้ในหลาย ๆ ครั้ง ข้อมูลที่เราต้องการถูกเก็บอยู่ในไฟล์ Excel (เช่น .xls และ .xlsx)

    ในบทความนี้ เราจะมาทำความรู้จักกับ readxl และ XLConnect ซึ่งเป็น packages สำหรับทำงานกับ Excel ในภาษา R กัน

    เราจะดูการใช้งานผ่านตัวอย่างการทำงานกับ Daily Transactions Dataset จาก Kaggle ที่ถูกเก็บในไฟล์ XLSX (”Daily Household Transactions.xlsx”):

    ข้อมูลใน ”Daily Household Transactions.xlsx”

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


    1. 1️⃣ Package 1. readxl
    2. 2️⃣ Package 2. XLConnect
      1. 📔 กรณีที่ 1. โหลดและสำรวจ Workbook
      2. ⬇️ กรณีที่ 2. โหลดข้อมูลจาก sheet
      3. 🖐️ กรณีที่ 3. จัดการ Sheet
      4. ➕ กรณีที่ 4. เพิ่มข้อมูลใน Sheet
      5. 💾 กรณีที่ 5. บันทึก Workbook
    3. 💪 Summary
    4. 😺 GitHub
    5. 📃 References
    6. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    1️⃣ Package 1. readxl

    readxl เป็น package สำหรับโหลดข้อมูลจาก Excel และมี function ที่เราจะเรียกใช้งานได้ คือ read_excel() ซึ่งต้องการ 2 arguments:

    1. path: ชื่อไฟล์ หรือ file path
    2. sheet: ชื่อหรือลำดับของ sheet ที่เก็บข้อมูลที่เราต้องการ

    ในการเริ่มต้นใช้งาน readxl เราจะติดตั้งและโหลด package:

    # Install readxl
    install.packages("readxl")
    
    # Load readxl
    library(readxl)
    

    จากนั้น เรียกใช้ read_excel() เพื่อโหลดข้อมูล:

    # Import Excel data with read_excel()
    all_transactions <- read_excel("Daily Household Transactions.xlsx",
                                   sheet = 1)
    
    # View the first few rows
    head(all_transactions)
    

    ผลลัพธ์:

    # A tibble: 6 × 8
      Date                Mode              Category Subcategory Note  Amount `Income/Expense` Currency
      <dttm>              <chr>             <chr>    <chr>       <chr>  <dbl> <chr>            <chr>   
    1 2018-09-20 12:04:08 Cash              Transpo… Train       2 Pl…     30 Expense          INR     
    2 2018-09-20 12:03:15 Cash              Food     snacks      Idli…     60 Expense          INR     
    3 2018-09-19 00:00:00 Saving Bank acco… subscri… Netflix     1 mo…    199 Expense          INR     
    4 2018-09-17 23:41:17 Saving Bank acco… subscri… Mobile Ser… Data…     19 Expense          INR     
    5 2018-09-16 17:15:08 Cash              Festiva… Ganesh Puj… Gane…    251 Expense          INR     
    6 2018-09-15 06:34:17 Credit Card       subscri… Tata Sky    Perm…    200 Expense          INR     
    

    Note: read_excel() มี parametres อื่น ๆ ที่เราสามารถตั้งค่าได้ เช่น:

    • range: ช่วงข้อมูลที่เราต้องการโหลด
    • col_names: ชื่อ columns
    • col_types: ประเภทข้อมูลในแต่ละ column
    • skip: จำนวน rows ที่เราจะข้ามในการโหลดข้อมูล เช่น เรากำหนด skip = 5, read_excel() จะโหลดข้อมูลตั้งแต่ row ที่ 6 เป็นต้นไป

    ดูคู่มือการใช้งาน read_excel() ทั้งหมดได้ที่ read_excel: Read xls and xlsx files.


    2️⃣ Package 2. XLConnect

    XLConnect เป็น package ที่ช่วยให้เราทำงานกับไฟล์ Excel จาก R ได้โดยตรง

    การใช้งาน XLConnect แบ่งได้เป็น 5 กรณี ดังนี้:

    1. โหลดและสำรวจ workbook
    2. โหลดข้อมูลจาก sheet
    3. จัดการ sheet
    4. เพิ่มข้อมูลใน sheet
    5. บันทึก workbook

    เราไปดูการใช้งานในแต่ละกรณีกัน

    .

    📔 กรณีที่ 1. โหลดและสำรวจ Workbook

    ในการเริ่มใช้งาน XLConnect เราจะต้องติดตั้งและโหลด package ก่อน:

    # Install
    install.packages("XLConnect")
    
    # Load
    library(XLConnect)
    

    จากนั้น เราสามารถโหลด Excel เราเข้ามาใน R ได้ด้วย loadWorkbook():

    # Load the workbook
    workbook <- loadWorkbook("Daily Household Transactions.xlsx")
    

    และดู sheet ทั้งหมดใน workbook ด้วย getSheets():

    # List sheets
    getSheets(workbook)
    

    ผลลัพธ์:

    [1] "All Transactions"
    

    ในตัวอย่าง จะเห็นว่า Excel ของเรามี 1 sheet ได้แก่ “All Transactions”

    .

    ⬇️ กรณีที่ 2. โหลดข้อมูลจาก sheet

    เมื่อเห็นโครงสร้างของไฟล์ Excel แล้ว เราสามารถโหลดข้อมูลจาก sheet ที่ต้องการได้ด้วย readWorksheet():

    # Get sheet data
    sheet1_data <- readWorksheet(workbook,
                                 sheet = "All Transactions")
    
    # Print data
    head(sheet1_data)
    

    ผลลัพธ์:

                     Date                  Mode       Category             Subcategory                                     Note Amount Income.Expense Currency
    1 2018-09-20 12:04:08                  Cash Transportation                   Train                     2 Place 5 to Place 0     30        Expense      INR
    2 2018-09-20 12:03:15                  Cash           Food                  snacks              Idli medu Vada mix 2 plates     60        Expense      INR
    3 2018-09-19 00:00:00 Saving Bank account 1   subscription                 Netflix                     1 month subscription    199        Expense      INR
    4 2018-09-17 23:41:17 Saving Bank account 1   subscription Mobile Service Provider                        Data booster pack     19        Expense      INR
    5 2018-09-16 17:15:08                  Cash      Festivals            Ganesh Pujan                              Ganesh idol    251        Expense      INR
    6 2018-09-15 06:34:17           Credit Card   subscription                Tata Sky Permanent Residence - Tata Play recharge    200        Expense      INR
    

    .

    🖐️ กรณีที่ 3. จัดการ Sheet

    ในการจัดการ sheet เราสามารถทำได้ 3 อย่าง:

    1. สร้าง sheet ใหม่: createSheet()
    2. เปลี่ยนชื่อ sheet: renameSheet()
    3. ลบ sheet: removeSheet()

    ยกตัวอย่างการสร้าง sheet ใหม่:

    # Create new sheets
    createSheet(workbook,
                name = "New")
    
    # List sheets
    getSheets(workbook)
    

    ผลลัพธ์:

    [1] "All Transactions" "New" 
    

    เปลี่ยนชื่อ sheet:

    # Rename the new sheet
    renameSheet(workbook,
                sheet = "New",
                newName = "Some Transactions")
    
    # List sheets
    getSheets(workbook)
    

    ผลลัพธ์:

    [1] "All Transactions"  "Some Transactions"
    

    และลบ sheet ทิ้ง:

    # Delete the new sheet
    removeSheet(workbook,
                sheet = "Some Transactions")
    
    # List sheets
    getSheets(workbook)
    

    ผลลัพธ์:

    [1] "All Transactions" 
    

    .

    ➕ กรณีที่ 4. เพิ่มข้อมูลใน Sheet

    เราสามารถใส่ข้อมูลลงใน sheet ได้ด้วย writeWorksheet()

    ยกตัวอย่างเช่น เราต้องการเพิ่มข้อมูลสรุปค่าใช้จ่ายตามประเภทการใช้จ่าย

    เราจะเริ่มจากสรุปค่าใช้จ่ายตามประเภทโดยใช้ dplyr package:

    # Load dplyr
    library(dplyr)
    
    # Calculate expense by category
    expense_by_cat <- sheet1_data |>
      
      # Filter for expense
      filter(Income.Expense == "Expense") |>
      
      # Group by category
      group_by(Category) |>
      
      # Calculate sum amount
      summarise(Sum = sum(Amount)) |>
        
      # Ungroup
      ungroup() |>
      
      # Sort by category
      arrange(desc(Sum))
    
    # View the results
    expense_by_cat
    

    (Note: อ่านเกี่ยวกับการใช้ dplyr ได้ที่นี่)

    ผลลัพธ์:

    # A tibble: 27 × 2
       Category                  Sum
       <chr>                   <dbl>
     1 Money transfer        606529.
     2 Investment            271858 
     3 Transportation        169054.
     4 Household             161646.
     5 subscription          114588.
     6 Food                   96403.
     7 Public Provident Fund  90000 
     8 Other                  87025.
     9 Family                 78582.
    10 Health                 66253.
    # ℹ 17 more rows
    # ℹ Use `print(n = ...)` to see more rows
    

    จากนั้น สร้าง sheet ใหม่เพื่อเก็บข้อมูลที่เราได้มา:

    # Create a new sheet
    createSheet(workbook,
                name = "Expense by Category")
    
    # Add data to "Expense by Catogory" sheet
    writeWorksheet(workbook,
                   data = expense_by_cat,
                   sheet = "Expense by Category")
    

    เมื่อเราเรียกดูข้อมูลจาก “Expense by Catogory” เราจะเห็นข้อมูลแบบนี้:

    # Read the sheet
    readWorksheet(workbook,
                  sheet = "Expense by Category")
    

    ผลลัพธ์:

                    Category       Sum
    1         Money transfer 606528.90
    2             Investment 271858.00
    3         Transportation 169053.78
    4              Household 161645.58
    5           subscription 114587.91
    6                   Food  96403.10
    7  Public Provident Fund  90000.00
    8                  Other  87025.28
    9                 Family  78582.20
    10                Health  66252.75
    11               Tourism  63608.85
    12                  Gift  40168.00
    13               Apparel  25373.82
    14     Recurring Deposit  22000.00
    15                  maid  21839.00
    16                  Cook  12443.00
    17                  Rent  10709.00
    18             Festivals   6911.00
    19               Culture   4304.36
    20                Beauty   4189.00
    21      Self-development   2357.00
    22             Education    537.00
    23              Grooming    400.00
    24           Social Life    298.00
    25   water (jar /tanker)    148.00
    26             Documents    100.00
    27      garbage disposal     67.00
    

    .

    💾 กรณีที่ 5. บันทึก Workbook

    จนถึงจุดนี้ สิ่งที่เราแก้ไขไปจะยังไม่ถูกบันทึกลงในไฟล์ Excel ของเรา

    เราต้องใช้ saveWorkbook() เพื่อบันทึกการเปลี่ยนแปลงทั้งหมดได้

    อย่างในตัวอย่าง เราจะบันทึกการเปลี่ยนแปลงทั้งหมดไปที่ workbook ใหม่ชื่อ “Daily Household Transactions (Updated).xlsx”:

    # Save the file
    saveWorkbook(workbook,
                 file = "Daily Household Transactions (Updated).xlsx")
    

    เมื่อเราเปิด working directory ดู เราจะเห็น Excel 2 ไฟล์:

    1. ไฟล์ต้นฉบับ
    2. ไฟล์ที่เราสร้างใหม่
    Workbook ต้นฉบับ (ซ้าย) และ workbook ที่เราสร้างใหม่ (ขวา)

    💪 Summary

    ในบทความนี้ เราได้เรียนรู้วิธีการทำงานกับ Excel ในภาษา R ผ่าน 2 packages ได้แก่:

    Package 1. readxl:

    FunctionFor
    read_excel()โหลดข้อมูลจาก Excel

    Package 2. XLConnect:

    FunctionFor
    loadWorkbook()โหลด workbook
    getSheets()ดู sheets ใน workbook
    readWorksheet()โหลดข้อมูลจาก sheet
    createSheet()สร้าง sheet
    renameSheet()เปลี่ยนชื่อ sheet
    removeSheet()ลบ sheet
    writeWorksheet()เพิ่มข้อมูลใน sheet
    saveWorkbook()บันทึก workbook

    😺 GitHub

    ดู code และ Excel ตัวอย่างได้ที่ 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:

  • if, for, while ใน Python: วิธีใช้ conditional statements, control flow, และ loop control ใน Python พร้อมตัวอย่าง

    if, for, while ใน Python: วิธีใช้ conditional statements, control flow, และ loop control ใน Python พร้อมตัวอย่าง

    ในบทความนี้ เราจะมาดูวิธีใช้ code 3 ประเภท ที่จะช่วยให้ Python code สามารถตัดสินใจแทนเราได้:

    1. Conditional statements: if, elif, else
    2. Control flow statements: for, while
    3. Loop control statements: continue, break, pass

    ก่อนไปดูวิธีใช้ทั้ง 3 ประเภท เราจะไปทำความรู้จักกับ comparison และ logical statement ซึ่งเราจะใช้ร่วมกับ code 3 ประเภทนี้กัน

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


    1. 🧮 1. Comparison & Logical Operators
      1. #️⃣ (1) Comparison Operators
      2. ♟️ (2) Logical Operators
    2. 🚦 2. Conditional Statements
    3. 🌊 3. Control Flow Statements
      1. 📦 (1) for Loop
      2. 🔁 (2) while Loop
    4. 🚄 4. Loop Control Statements
    5. 💪 5. Summary
    6. 😺 GitHub
    7. 📃 References

    🧮 1. Comparison & Logical Operators

    #️⃣ (1) Comparison Operators

    Comparison operators เป็นเครื่องหมายใช้เปรียบเทียบข้อมูล:

    OperatorDescription
    ==เท่ากับ
    !=ไม่เท่ากับ
    >มากกว่า
    >=มากกว่า/เท่ากับ
    <น้อยกว่า
    <=น้อยกว่า/เท่ากับ

    โดย comparison operators จะให้ผลลัพธ์เป็น Boolean (True, False) กลับมา เช่น:

    # True statement
    10 > 5
    

    ผลลัพธ์:

    True
    

    และ:

    # False statement
    10 < 5
    

    ผลลัพธ์:

    False
    

    ♟️ (2) Logical Operators

    Logical operators เป็น keywords เชื่อมเงื่อนไข ช่วยให้เราประเมินหลายเงื่อนไขพร้อมกันได้:

    OperatorDescription
    andLogical AND
    orLogical OR
    notLogical NOT

    โดยผลลัพธ์เป็นไปตาม truth table:

    Condition 1OperatorCondition 2Result
    TrueandTrueTrue
    TrueandFalseFalse
    FalseandFalseFalse
    TrueorTrueTrue
    TrueorFalseTrue
    FalseorFalseFalse
    notTrueFalse
    notFalseTrue

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

    # True and True
    1 == 1 and 2 < 4
    

    ผลลัพธ์:

    True
    

    🚦 2. Conditional Statements

    Conditional statements ใช้กำหนดเงื่อนไขว่า code จะรันได้เมื่อไร และมีอยู่ 3 แบบ ได้แก่:

    • if: กำหนดเงื่อนไขแรก
    • elif: กำหนดเงื่อนไขเพิ่มเติม
    • else: รันเมื่อตรงกับเงื่อนไขอื่น ๆ ที่ไม่ใช่ if และ elif

    ยกตัวอย่างเช่น เราต้องการ print ข้อความแจ้งเตือนตามสภาพอากาศ:

    # Weather today
    weather = "snowy"
    

    เราสามารถทำได้แบบนี้:

    # Print when sunny
    if weather == "sunny":
        print("It's a sunny day. Don't forget your sunscreen!")
    
    # Print when rainy
    elif weather == "rainy":
        print("It's raining. Remember to bring an umbrella!")
    
    # Print when other conditions
    else:
        print("Likely chilly. Wear a jacket!")
    

    ผลลัพธ์:

    Likely chilly. Wear a jacket!
    

    อธิบาย code:

    • if block: ประเมินว่า weather เป็น "sunny" ไหม ถ้าใช่ จะ print "It's a sunny day. Don't forget your sunscreen!"
    • elif block: weather เป็น "rainy" ไหม ถ้าใช่ จะ print "It's raining. Remember to bring an umbrella!"
    • else block: ถ้า weather เป็นค่าอื่น ๆ (เช่น "snowy") จะ print "Likely chilly. Wear a jacket!"

    เพราะ weather มีค่าตรงกับ else block เราจึงได้ผลลัพธ์เป็น "Likely chilly. Wear a jacket!"


    🌊 3. Control Flow Statements

    Control flow statements ใช้ควบคุมลำดับการทำงานของ code และมีอยู่ 2 แบบ ได้แก่:

    1. for: รัน code ตามจำนวนข้อมูลที่มี
    2. while: รัน code จนกว่าเงื่อนไขจะไม่เป็นจริง

    📦 (1) for Loop

    ตัวอย่าง for loop เช่น print ชื่อแขกในงาน:

    # Guest list
    guests = ["James Bond", "John Wick", "Jack Reacher", "Jason Bourne", "Jack Ryan"]
    
    # Print guest names
    for name in guests:
        
        # Print name
        print(name)
    

    ผลลัพธ์:

    James Bond
    John Wick
    Jack Reacher
    Jason Bourne
    Jack Ryan
    

    อธิบาย code:

    • guest = ...: สร้าง list เก็บรายชื่อแขก
    • for ...: นำชื่อแขกใน list มา print จนกว่าจะครบทุกคน

    🔁 (2) while Loop

    ตัวอย่าง while loop เช่น นับเลข 1 ถึง 10:

    # Starting number
    number = 1
    
    # Count to 10
    while number <= 10:
        
        # Print number
        print(number)
        
        # Add 1 to number
        number += 1
    

    ผลลัพธ์:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    

    อธิบาย code:

    • number = 1: กำหนดเลขเริ่มต้น
    • while ...: print number และปรับ number ให้สูงขึ้น 1 ค่า ทำอย่างนี้วนไปจนกว่า number จะมากกว่า 10 (number <= 10 ไม่เป็นจริง)

    🚄 4. Loop Control Statements

    Loop control statements ใช้ควบคุมการทำงานของ control flow และมีอยู่ 3 แบบ ได้แก่:

    1. continue: skip ไป item ถัดไป
    2. break: หยุดการทำงานของ control flow
    3. pass: placeholder สำหรับใส่ code ในอนาคต

    ยกตัวอย่างเช่น เรามีรายการของที่ต้องซื้อ และแต่ละอย่างมี action ไม่เหมือนกัน:

    # A shopping list program
    shopping_list = ["milk", "bread", "chips", "apple", "toothpaste", "chocolate"]
    
    # Loop through the list
    for item in shopping_list:
    
        # Skip item if chip
        if item == "chips":
            print("Chips are unhealthy. Skipping ...")
            continue
        
        # Stop the loop if toothpaste
        if item == "toothpaste":
            print("Found toothpaste, done shopping early!")
            break
        
        # Do nothing if milk
        if item == "milk" or item == "bread":
            pass
        
        # Print item
        print("Putting", item, "into the cart.")
    

    ผลลัพธ์:

    Putting milk into the cart.
    Putting bread into the cart.
    Chips are unhealthy. Skipping ...
    Putting apple into the cart.
    Found toothpaste, done shopping early!
    

    อธิบาย code:

    • shopping_list = ...: สร้าง list เก็บรายการซื้อของ
    • if item == "chips" block: ประเมินว่า item ใช่ "chip" ไหม ถ้าใช่ ให้ print "Chips are unhealthy. Skipping ..." และข้ามไป item ถัดไป (continue)
    • if item == "toothpaste" block: ประเมินว่า item ใช่ "toothpaste" ไหม ถ้าใช่ ให้ print "Found toothpaste, done shopping early!" และจบ loop ทันที (break)
    • if item == "milk" … block: ประเมินว่า item ใช่ "milk" หรือ "bread" ไหม ถ้าใช่ ไม่ต้องทำอะไร (pass)
    • print ...: print ว่า กำลังเอา item ใส่ตระกร้า

    สังเกตว่า:

    • มีแค่ milk, bread, apple ที่ “กำลังใส่ตระกร้า” เพราะ milk และ bread อยู่ใน pass block และ apple ไม่ได้อยู่ใน block ไหนเลย
    • Chip ถูกข้ามไป เพราะอยู่ใน continue block
    • Toothpaste อยู่ใน break block และมาก่อน chocolate ทำให้เราไม่เห็น chocolate เพราะ toothpaste

    💪 5. Summary

    ในบทความนี้ เราได้ไปดูวิธีการเขียน code ใน Python เพื่อให้ code ตัดสินใจได้:

    Comparison operators:

    OperatorDescription
    ==เท่ากับ
    !=ไม่เท่ากับ
    >มากกว่า
    >=มากกว่า/เท่ากับ
    <น้อยกว่า
    <=น้อยกว่า/เท่ากับ

    Logical operators:

    OperatorDescription
    andLogical AND
    orLogical OR
    notLogical NOT

    Conditional statements:

    StatementDescription
    ifกำหนดเงื่อนไขแรก
    elifกำหนดเงื่อนไขเพิ่มเติม
    elseทำ action เมื่อเข้าเงื่อนไขอื่น ๆ

    Control flow statements:

    StatementDescription
    forวนจนครบทุก item
    whileวนจนกว่าเงื่อนไขจะเป็น False

    Loop control statements:

    StatementDescription
    continueSkip
    breakStop
    passDo nothing

    😺 GitHub

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


    📃 References

  • Building Judgment: สรุป 3 แนวทางในการพัฒนาความคิดให้เฉียบคม จากหนังสือ The Almanack of Naval Ravikant โดย Eric Jorgenson — Think Clearly, Mental Models, และ Read

    Building Judgment: สรุป 3 แนวทางในการพัฒนาความคิดให้เฉียบคม จากหนังสือ The Almanack of Naval Ravikant โดย Eric Jorgenson — Think Clearly, Mental Models, และ Read

    The Almanack of Naval Ravikant เป็นหนังสือของ Eric Jorgenson นักเขียนเกี่ยวกับ startups ซึ่งรวบรวมปรัชญาการใช้ชีวิตและความมั่งคั่ง (wealth) ของ Naval Ravikant นักลงทุนที่ประสบความสำเร็จจากการลงทุนในบริษัทอย่าง Uber, FourSqure, และ Twitter (X) และเป็น CEO ของ AngelList บริษัทที่ช่วยให้ startups ได้พบกับ angel investors เอาไว้

    ในบทความนี้ เราจะสรุปบทเรียน Building Judgment ซึ่งเป็นบทที่ 2 จาก 5 ในหนังสือ

    บทสรุปแบ่งออกเป็น 4 กลุ่ม ได้แก่:

    1. What and why of judgment: นิยามและความสำคัญของ judgment
    2. Think clearly: วิธีคิดให้ทะลุปรุโปร่ง
    3. Mental models: หลักการคิดที่ควรมี
    4. Read: แนวคิดเกี่ยวกับการอ่าน

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


    หน้าปกหนังสือ The Alamack of Naval Ravikant บน Amazon

    1. ⚖️ What & Why of Judgment
    2. 😎 Think Clearly
      1. 🌱 Basic Knowledge: Start from the Ground Up
      2. 🥠 Reality: See Past the Identity
      3. 🙂 Additional Tips: Honesty & Criticism
    3. 🧠 Mental Models
    4. 📖 Read
      1. 🔖 What & How to Read
    5. 🌻 Summary
    6. 🔥 Get The Almanack of Naval Ravikant

    ⚖️ What & Why of Judgment

    The direction you’re heading in matters more than how fast you move, especially with leverage.

    — Naval Ravikant

    Judgment ในนิยามของ Naval คือ การประยุกต์ใช้ wisdom กับปัญหาภายนอก

    Wisdom หมายถึง ความสามารถในการมองเห็นผลลัพธ์ในระยะยาวของการกระทำ

    ดังนั้น judgment คือ ความสามารถในการมองเห็นผลลัพธ์ในระยะยาวของการกระทำภายนอก ซึ่งทำให้เราสามารถหาประโยชน์จากการตัดสินใจต่าง ๆ ในชีวิตได้

    Judgment = wisdom(external problems)
    

    ในยุคที่เทคโนโลยีพัฒนาอย่างรวดเร็ว judgment มีความสำคัญ เพราะเทคโนโลยีสามารถขยาย impact ของการตัดสินใจของเราได้หลายเท่าตัว

    ยกตัวอย่าง เรามีไอเดียและโพสต์ไอเดียลง social media เราสามารถเข้าถึงคนที่เราต้องการได้ภายในเวลาอันสั้น และถ้าไอเดียนี้ดี เราก็จะได้ผลตอบรับที่ดีจำนวนมากกลับมา แต่ถ้าเป็นไอเดียไม่เป็นที่ยอมรับของสังคม เราก็จะได้รับแรงต้านมหาศาลเช่นกัน

    ถ้าเรามี judgment ที่ดีกว่าคนอื่นเพียงนิดเดียว เราก็สามารถเห็นผลลัพธ์ที่แตกต่างกันได้อย่างสิ้นเชิง

    In an age of leverage, one correct decision can win everything.

    — Naval Ravikant

    ทั้งนี้ เรามี 3 วิธีในการพัฒนา judgment ของเรา ได้แก่:

    1. Think clearly
    2. Mental models
    3. Read

    ไปดูรายละเอียดของแต่ละวิธีกัน


    😎 Think Clearly

    “Clear thinker” is a better compliment than “smart.”

    — Naval Ravikant

    Think clearly คือ การคิดที่ตั้งอยู่บนพื้นฐานของความเป็นจริง (reality) และประกอบด้วย 2 ส่วน ได้แก่:

    1. ความรู้ขั้นพื้นฐาน
    2. การมองเห็นความเป็นจริง

    .

    🌱 Basic Knowledge: Start from the Ground Up

    Real knowledge is intrinsic, and it’s built from the ground up.

    — Naval Ravikant

    คนที่มี judgment ที่ดีมักมีความรู้ขั้นพื้นฐานที่ดี เพราะเมื่อเรามีความรู้พื้นฐานแล้ว เราสามารถต่อยอดเป็นความรู้ที่ซับซ้อนมากขึ้นได้

    ในมุมมองของ Naval คนที่ฉลาดมักจะเป็นคนที่เข้าใจความรู้พื้นฐานอย่างท่องแท้ ยกตัวอย่างเช่น Richard Feynman นักฟิสิกส์ที่ได้ Nobel Prize ในปี 1965 ซึ่งสามารถอธิบายคณิตศาสตร์ได้โดยเริ่มจากการนับเลขและต่อยอดไปเรื่อย ๆ ไปจนถึงพีชคณิตและตรีโกณมิติ (precalculus) โดยไม่ใช้นิยามใด ๆ แต่ใช้ chain of logic อย่างเดียว

    ถ้าเราสามารถอธิบาย concept ที่ซับซ้อนให้เด็กเข้าใจได้ แสดงว่า เรามีความรู้พื้นฐานที่แท้จริง แต่ถ้าเราทำไม่ได้ แสดงว่าเรากำลังจำ concept โดยไม่ได้เข้าใจความรู้พื้นฐานจริง ๆ

    .

    🥠 Reality: See Past the Identity

    The hard thing is seeing the truth.

    — Naval Ravikant

    คนที่มี judgment ที่ดี คือ คนที่เข้าใกล้ reality ได้มากที่สุด

    การเข้าใกล้ reality ไม่ใช่เรื่องง่าย เพราะมีปัจจัยหลายอย่างที่ขัดขวางไม่ให้เราเห็น reality เช่น:

    • Desires: สิ่งที่เราต้องการให้เป็น
    • Expectations: ความคาดหวัง
    • Beliefs: ความเชื่อ
    • Habits: ความเคยชิน

    Naval เรียกปัจจัยเหล่านี้รวมกันว่า identity หรือ ego ที่ก่อรูปเป็นตัวเราและคอยกำกับการกระทำของเรา

    What we wish to be true clouds our perception of what is true.

    — Naval Ravikant

    ถ้าเราอยากจะเข้าใกล้ reality ให้ได้มากที่สุด เราจะต้องตัดสินใจโดยไม่ใช้ identity/ego เพราะการใช้ identity/ego หมายถึง การใช้ความเชื่อหรือความเคยชินที่มีมาแต่เดิม และอาจไม่ใช่สิ่งที่สอดคล้องกับความเป็นจริงในปัจจุบัน

    ยกตัวอย่างเช่น เราเชื่อว่าธุรกิจกำลังไปได้ดี ทำให้เราตัดสินใจลงทุนเพิ่ม ทั้ง ๆ ที่เศรษฐกิจกำลังซบเซา ทำให้การตัดสินใจของเราส่งผลเสีย (แทนที่จะเป็นผลดี) ต่อธุรกิจ

    ยิ่งเราเข้าใกล้ reality ได้มากเท่าไร เราก็ยิ่งมี judgment ที่ดีขึ้นเท่านั้น

    .

    🙂 Additional Tips: Honesty & Criticism

    You should never, ever fool anybody, and you are the easiest person to fool.

    — Richard Feynman

    Naval แนะนำอีก 2 เคล็ดลับที่จะช่วยให้เราคิดได้ดีขึ้น ได้แก่:

    1. Radical honesty
    2. Praise specifically, criticise generally

    Radical honesty หมายถึง เราควรซื่อสัตย์ต่อทั้งตัวเองและคนอื่น เพราะคนที่ถูกหลอกง่ายที่สุดคือตัวเอง

    ถ้าเราโกหกคนอื่น เราจะเชื่อคำโกหกของตัวเอง ทำให้เราไม่สามารถเป็นตัวของตัวเองได้ รวมทั้งทำให้เราหลุดจากความเป็นจริง

    Praise specifically, criticise generally เป็นแนวคิดที่ Naval ได้มาจาก Warren Buffet ซึ่งหมายถึง:

    • เวลาที่เราวิพากวิจารณ์ใคร เราควรวิจารณ์แนวทางมากกว่าตัวบุคคล
    • เวลาที่เราชื่นชมใคร ให้เราชมตัวบุคคล

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

    • ถ้าเราเห็นพนักงานทำงานไม่ดี ให้เราวิจารณ์แนวทางในการทำงานที่พนักงานใช้
    • ถ้าเราเห็นพนักงานทำงานได้ดี เราควรชื่นชมพนักงาน เพราะเป็นตัวอย่างคนทำงานที่ดี

    การทำอย่างนี้จะช่วยทำให้คนอื่นอยากทำงานกับเรา มากกว่าต่อต้านเรา เพราะเราไม่ได้โจมตี identity/ego ของคนอื่น


    🧠 Mental Models

    What you want is principles. You want mental models.

    — Naval Ravikant

    Mental model เป็นเหมือนแผนที่ที่บอกว่า สิ่งต่าง ๆ ทำงานยังไง เช่น ถ้า X เกิดขึ้น Y จะตามมา

    ถ้าเราอยากจะมี judgment ที่ดี เราควรมี mental models ที่จะช่วยให้เราตัดสินใจได้ถูกต้องและแม่นยำ

    Naval แนะนำ 12 mental models ที่น่าสนใจ:

    1. Evolution: ทุกอย่างที่เกิดขึ้นในอารยธรรมสามารถอธิบายได้ด้วยหลัก evolution ที่ว่า ใครจะอยู่รอดและได้สืบพันธุ์ต่อไป
    2. Inversion: แนวคิดในการตัดตัวเลือกที่ไม่ใช่ แทนการมองหาตัวเลือกที่ใช่
    3. Complexity theory: Naval เชื่อว่า คนเราใสซื่อจนเกินไปและมีความสามารถในการทำนายอนาคตที่แย่มาก
    4. Economics: ความรู้เชิงเศรษฐศาสตร์ต่าง ๆ เช่น demand-supply, game theory
    5. Principal-agent problem: แนวคิดที่ว่า ความไม่สอดคล้องอาจเกิดขึ้นได้เมื่อเรา (principal) ให้คนอื่น (agent) ทำงานให้กับเรา เพราะ agent ไม่สามารถรู้ความต้องการของ principal ได้ตลอดเวลา เช่น เราฝากเพื่อนซื้อข้าว เพื่อนอาจซื้อข้าวผัดมาให้เพราะเห็นเรากินข้าวผัดในอดีต แต่วันนี้ เราอยากกินก๋วยเตี๋ยว ทำให้ข้าวที่ซื้อมาไม่ตรงโจทย์
    6. Compound interest: แนวคิดที่ว่า ดอกเบี้ยทบต้นไม่ได้ใช้ได้กับการเงินเท่านั้น แต่ยังใช้ได้กับด้านอื่น ๆ ของชีวิต เช่น การหาลูกค้า ถ้าบริษัทมีผู้ใช้ 100 คนในเดือนแรก และมียอดการเติบโตของผู้ใช้ 20% ต่อเดือน ภายใน 1 ปี บริษัทจะมีผู้ใช้งานถึงเกือบ 900 คนใน
    7. Basic math: ความรู้ทางคณิตศาสตร์ เช่น การคิดบวกลบเลข ความน่าจะเป็น และสถิติ
    8. Black swans: แนวคิดของ Nassim Nicholas Taleb นักวิทยาศาสตร์และนักปรัชญา ซึ่งหมายถึง เหตุการณ์ที่มีโอกาสเกิดขึ้นน้อยมาก แต่มีผลกระทบในวงกว้าง Naval แนะนำให้ศึกษางานของ Nassim ถ้าต้องการศึกษาเพิ่มเติม
    9. Calculus: การคำนวณ output โดยใช้ input และ functions
    10. Falsifiability: falsifiable หมายถึง สามารถพิสูจน์ว่าเป็น/ไม่เป็นจริงได้ และแนวคิดเป็นแก่นหลักของวิทยาศาสตร์ ทฤษฎีใดที่ไม่สามารถ falsify ได้เป็นทฤษฎีที่ไม่ควรยึดถือ เพราะเราพิสูจน์ไม่ได้ว่าเป็นจริง/ไม่เป็นจริง
    11. If you can’t decide, then the answer is no: ถ้าเราตัดสินใจไม่ได้ (เช่น จะไปเรียนต่อไหม) คำตอบคือไม่ เพราะในปัจจุบัน เรามีตัวเลือกมากมาย และเราควร say “yes” ก็ต่อเมื่อเรามั่นใจในตัวเลือกจริง ๆ แล้วเท่านั้น
    12. Run uphill: ถ้าเรารู้สึก 50-50 กับการตัดสินใจยาก ๆ ให้เราเลือกทางที่ยากกว่า เพราะทางที่ยากในระยะสั้นมักให้ผลดีในระยะยาว เหมือนกับการวิ่ง เราจะเหนื่อยในระหว่างวิ่ง แต่สุดท้ายเราจะมีสุขภาพที่ดีในระยะยาว

    📖 Read

    Read a lot—just read.

    — Naval Ravikant

    แนวทางสุดท้ายในการพัฒนา judgment คือ การอ่าน

    การอ่านคือ superpower ซึ่งเราสามารถพัฒนาได้

    สำหรับคนที่ต้องการฝึกทักษะการอ่าน Naval แนะนำให้เริ่มจากการอ่านสิ่งที่ชอบจนกว่าเราจะรักในการอ่าน

    Read what you love until you love to read.

    — Naval Ravikant

    ในช่วงแรก เราไม่ต้องสนใจว่า หนังสือที่เราอ่านเกี่ยวกับเรื่องอะไร ขอให้เป็นสิ่งที่เราชอบก็พอ และอ่านให้เยอะ ไม่ว่าจะเป็นอะไรก็ตาม

    .

    🔖 What & How to Read

    The problem with saying “just read” is there is so much junk out there.

    — Naval Ravikant

    Naval มีเทคนิคในการอ่านเพื่อสร้างความรู้ 5 ข้อ ได้แก่:

    1. Basic knowledge: อ่านหนังสือที่มีความรู้พื้นฐาน เช่น คณิตศาสตร์ วิทยาศาสตร์ และปรัชญา
    2. Classic work: อ่านหนังสือต้นฉบับหรือหนังสือ classic เช่น ถ้าเราต้องการอ่านเกี่ยวกับ evolution เราควรอ่านงานของ Charles Darwin ก่อน แล้วค่อยอ่านหนังสือของคนอื่นที่เขียนต่อยอดจาก Charles Darwin เป็นต้น
    3. No obligation to finish a book: เราอ่านเพื่อทำความเข้าใจไอเดียพื้นฐานของหนังสือ เราไม่จำเป็นต้องอ่านหนังสือให้จบทั้งเล่ม ถ้าเรารู้สึกว่าเข้าใจไอเดียพื้นฐานในหนังสือแล้ว เราสามารถข้ามไปเล่มถัดไปได้ และกลับมาดูหนังสือเล่มเก่าอีกครั้งเมื่อต้องการทบทวนความรู้
    4. You are what you read: เลือกหนังสือที่อ่านให้ดี เพราะหนังสือจะเหมือนเนื้อเพลงที่เล่นวนอยู่ในหัวเรา เราจะกลายเป็นสิ่งที่เราอ่าน
    5. Read to teach: อ่านโดยมีความตั้งใจว่าจะอธิบายให้คนอื่นฟัง การทำเช่นนี้จะทำให้เราเข้าใจสิ่งที่อ่านมากขึ้น

    🌻 Summary

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

    แนวทางในการพัฒนา judgment มีอยู่ 3 แนวทาง ได้แก่:

    1. Think clearly: คิดโดยตั้งอยู่บนพื้นฐานของความเป็นจริง โดยเราต้องมี (1) ความรู้พื้นฐาน และ (2) การตัดสินใจโดยไม่ใช้ identity/ego
    2. Mental models: สะสมแนวคิดในการตัดสินใจ เช่น evolution, inversion, complexity theory
    3. Read: อ่านให้เยอะเพื่อสะสมความรู้พื้นฐานและหลีกเลี่ยงหนังสือที่ไม่ดี

    🔥 Get The Almanack of Naval Ravikant

    สำหรับคนที่สนใจเนื้อหาของหนังสือและอยากอ่านเพิ่มเติม สามารถซื้อหนังสือได้ตาม link ด้านล่าง:

    Note: ใครที่สนใจอ่านต้นฉบับภาษาอังกฤษแบบ e-book หรือ PDF สามารถดาวน์โหลดฟรีได้ที่ navalmanack.com

  • 4 วิธีการใช้ getSymbols() เพื่อโหลดข้อมูลการเงินในภาษา R — ตัวอย่างการโหลดข้อมูลหุ้น Apple

    4 วิธีการใช้ getSymbols() เพื่อโหลดข้อมูลการเงินในภาษา R — ตัวอย่างการโหลดข้อมูลหุ้น Apple

    ในบทความนี้ เราจะมาทำความรู้จักกับ getSymbols() จาก quantmod package ซึ่งใช้โหลดข้อมูลทางการเงิน เช่น ข้อมูลหุ้น และข้อมูลทางเศรษฐกิจ กัน

    โดยเราจะไปดู 4 วิธีการใช้งาน ได้แก่:

    1. Basics: การใช้งาน getSymbols() เบื้องต้น
    2. Advanced: การใช้งานขั้นสูง
    3. View columns: การดู column ข้อมูล
    4. Visualise data: การสร้างกราฟข้อมูล

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


    1. 💻 Install & Import
    2. 1️⃣ Basics: 5 Parametres to Know
      1. 💲 Symbols
      2. 🏦 src
      3. 🏧 auto.assign
      4. 🌲 env
      5. 📆 from, to
    3. 2️⃣ Advanced: Set Defaults
      1. 🌍 getDefaults(), setDefaults()
      2. 💹 setSymbolLookup(), getSymbolLookup()
      3. 💾 saveSymbolLookup(), loadSymbolLookup()
    4. 3️⃣ View Columns
    5. 4️⃣ Visualise Data
    6. 💪 Summary
    7. 😺 GitHub
    8. 📃 References
    9. ✅ R Book for Psychologists: หนังสือภาษา R สำหรับนักจิตวิทยา

    💻 Install & Import

    ในการใช้งาน getSymbols() เราจะต้องเริ่มจากการติดตั้งและโหลด quantmod package ก่อน แบบนี้:

    # Install the packages
    install.packages("quantmod")
    
    # Load the packages
    library(quantmod)
    

    1️⃣ Basics: 5 Parametres to Know

    ในการใช้งานพื้นฐาน getSymbols() มี 5 parametres หลักที่เราควรรู้ ได้แก่:

    1. Symbols: ตัวย่อชื่อข้อมูล
    2. src: แหล่งข้อมูล
    3. auto.assign: ให้โหลด (TRUE) หรือแสดงข้อมูล (FALSE)
    4. env: environment สำหรับโหลดข้อมูล
    5. from และ to: ช่วงเวลาของข้อมูล

    เราไปดูวิธีใช้งานแต่ละ parametre กัน

    .

    💲 Symbols

    ในขั้นแรกของการโหลดข้อมูลการเงินด้วย getSymbols() ให้เราระบุชื่อข้อมูลที่เราต้องการ เช่น:

    ข้อมูลชื่อข้อมูล
    AppleAAPL
    GoogleGOOG
    MicrosoftMSFT
    NVIDIANVDA

    ในบทความนี้ เราจะลองโหลดข้อมูลหุ้น Apple กัน ซึ่งเราสามารถกำหนด Symbols ได้แบบนี้:

    # Import Apple data
    getSymbols("AAPL")
    

    เมื่อรันแล้ว เราจะได้ตัวแปรประเภท xts (time series object) ชื่อ AAPL มา ซึ่งเราดูข้อมูลในตัวแปรนี้ได้ด้วย head():

    # Print result
    head(AAPL)
    

    ผลลัพธ์:

               AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
    2007-01-03  3.081786  3.092143 2.925000   2.992857  1238319600      2.518541
    2007-01-04  3.001786  3.069643 2.993571   3.059286   847260400      2.574443
    2007-01-05  3.063214  3.078571 3.014286   3.037500   834741600      2.556108
    2007-01-08  3.070000  3.090357 3.045714   3.052500   797106800      2.568732
    2007-01-09  3.087500  3.320714 3.041071   3.306071  3349298400      2.782115
    2007-01-10  3.383929  3.492857 3.337500   3.464286  2952880000      2.915257
    

    จะเห็นได้ว่า นอกจากวันที่แล้ว ข้อมูลเรายังประกอบไปด้วย 6 columns ดังนี้:

    1. Open: ราคาเปิด
    2. High: ราคาสูงสุด
    3. Low: ราคาต่ำสุด
    4. Close: ราคาปิด
    5. Volume: ปริมาณการซื้อขาย
    6. Adjusted: ราคาปรับปรุง

    ในกรณีที่เราต้องการโหลดข้อมูลหุ้นหลายตัวพร้อมกัน เราสามารถใช้ character vector ช่วยได้แบบนี้:

    # Load multiple instruments
    getSymbols(c("AAPL", "GOOGL", "MSFT", "NVDA"))
    

    .

    🏦 src

    src ใช้กำหนดแหล่งข้อมูลที่ getSymbols() จะไปดึงข้อมูลมา

    โดย default, src ถูกตั้งไว้ให้ดึงข้อมูลจาก Yahoo! Finance ("yahoo")

    แสดงว่า เราสามารถเขียน code เพื่อดึงข้อมูล Apple จาก Yahoo! Finance ได้ทั้งแบบนี้:

    # Import Apple data
    getSymbols("AAPL")
    

    และแบบนี้:

    # Import Apple data
    getSymbols("AAPL", src = "yahoo")
    

    ทั้งนี้ getSymbols() มีแหล่งข้อมูลอื่น ๆ ให้เราเลือกใช้งานได้ เช่น:

    • Federal Reserve Economic Data ("FRED")
    • Oanda ("oanda")

    นอกจากแหล่งข้อมูลออนไลน์แล้ว เรายังสามารถโหลดข้อมูลแบบออฟไลน์ได้ เช่น:

    • CSV ("csv")
    • RData ("RData")

    ยกตัวอย่างเช่น โหลดข้อมูล Apple จาก CSV:

    # Load csv data
    getSymbols("AAPL", src = "csv")
    

    Note: การโหลดข้อมูล CSV ด้วย getSymbols() มีเงื่อนไข 4 อย่าง ได้แก่:

    1. มีชื่อไฟล์เป็นชื่อหุ้น (เช่น AAPL.csv)
    2. มี header
    3. Column แรกจะต้องเป็น datetime (เช่น 2025-05-25)
    4. Column ที่เหลือควรมีชื่อและข้อมูลดังนี้:
      1. Open: ข้อมูลราคาเปิด
      2. High: ข้อมูลราคาสูงสุด
      3. Low: ข้อมูลราคาต่ำสุด
      4. Close: ข้อมูลราคาปิด
      5. Volume: ข้อมูลปริมาณการซื้อขาย
      6. Adjusted: ข้อมูลราคาปรับปรุง

    .

    🏧 auto.assign

    auto.assign ใช้กำหนดว่า getSymbols() จะโหลดข้อมูลมาไว้ใน global environment หรือแสดงข้อมูลที่โหลดมาได้

    โดย default, auto.assign เป็น TRUE ซึ่งทำให้เราได้ตัวแปรที่เก็บข้อมูลการเงินมาไว้ใน global environment ของเรา โดยไม่ต้องกำหนดตัวแปรเอง

    ทั้งนี้ ในกรณีที่เราต้องการกำหนดตัวแปรเอง ให้เราเปลี่ยน auto.assign เป็น FALSE แบบนี้:

    # Set auto.assign to FALSE to assign to custom variable
    apple_data <- getSymbols("AAPL", auto.assign = FALSE)
    

    ถ้าเรากำหนดให้ auto.assign = FALSE โดยไม่จัดเก็บไว้ในตัวแปร getSymbols() จะแสดงข้อมูลใน console ของเรา:

    # Set auto.assign to FALSE without variable assignment
    getSymbols("AAPL", auto.assign = FALSE)
    

    ผลลัพธ์:

                AAPL.Open  AAPL.High   AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
    2007-01-03   3.081786   3.092143   2.925000   2.992857  1238319600      2.518541
    2007-01-04   3.001786   3.069643   2.993571   3.059286   847260400      2.574442
    2007-01-05   3.063214   3.078571   3.014286   3.037500   834741600      2.556108
    2007-01-08   3.070000   3.090357   3.045714   3.052500   797106800      2.568732
    2007-01-09   3.087500   3.320714   3.041071   3.306071  3349298400      2.782115
    2007-01-10   3.383929   3.492857   3.337500   3.464286  2952880000      2.915257
    2007-01-11   3.426429   3.456429   3.396429   3.421429  1440252800      2.879192
    2007-01-12   3.378214   3.395000   3.329643   3.379286  1312690400      2.843727
    2007-01-16   3.417143   3.473214   3.408929   3.467857  1244076400      2.918262
    2007-01-17   3.484286   3.485714   3.386429   3.391071  1646260000      2.853645
           ...                                                                      
    2025-06-05 203.500000 204.750000 200.149994 200.630005    55126100    200.630005
    2025-06-06 203.000000 205.699997 202.050003 203.919998    46607700    203.919998
    2025-06-09 204.389999 206.000000 200.020004 201.449997    72862600    201.449997
    2025-06-10 200.600006 204.350006 200.570007 202.669998    54672600    202.669998
    2025-06-11 203.500000 204.500000 198.410004 198.779999    60989900    198.779999
    2025-06-12 199.080002 199.679993 197.360001 199.199997    43904600    199.199997
    2025-06-13 199.729996 200.369995 195.699997 196.449997    51447300    196.449997
    2025-06-16 197.300003 198.690002 196.559998 198.419998    43020700    198.419998
    2025-06-17 197.199997 198.389999 195.210007 195.639999    38856200    195.639999
    2025-06-18 195.940002 197.570007 195.070007 196.580002    45350400    196.580002
    

    .

    🌲 env

    env ใช้กำหนด environment ที่ใช้เก็บข้อมูล ซึ่งโดย default, getSymbols() จะโหลดข้อมูลไว้ใน global environment

    ในการใช้ env กำหนด environment ที่ต้องการ เราจะต้องเริ่มจากสร้าง environment ขึ้นมาก่อนด้วย new.env():

    # Create a new environment
    my_env <- new.env()
    

    จากนั้น โหลดข้อมูลเข้าไปใน environment ใหม่:

    # Load data into the environment
    getSymbols("AAPL", env = my_env)
    

    เราสามารถดูตัวแปรที่เก็บไว้ใน environment ได้ด้วย ls():

    # List all variables in environment
    ls(envir = my_env)
    

    และดูข้อมูลได้ด้วย $ เช่น:

    # Show Apple data
    head(my_env$AAPL)
    

    ผลลัพธ์:

               AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
    2007-01-03  3.081786  3.092143 2.925000   2.992857  1238319600      2.518541
    2007-01-04  3.001786  3.069643 2.993571   3.059286   847260400      2.574442
    2007-01-05  3.063214  3.078571 3.014286   3.037500   834741600      2.556109
    2007-01-08  3.070000  3.090357 3.045714   3.052500   797106800      2.568732
    2007-01-09  3.087500  3.320714 3.041071   3.306071  3349298400      2.782115
    2007-01-10  3.383929  3.492857 3.337500   3.464286  2952880000      2.915256
    

    .

    📆 from, to

    from ใช้กำหนดวันแรกของข้อมูล และ to กำหนดวันสุดท้ายของข้อมูล

    ยกตัวอย่างเช่น เราต้องการโหลดข้อมูล Apple ในเดือนพฤษภาคม 2025:

    # Load data for May 2025
    apple_data_2025_05 = getSymbols("AAPL",
                                    auto.assign = FALSE,
                                    from = "2025-05-01",
                                    to = "2025-05-31")
    
    # Print results
    print("First three records:")
    head(apple_data_2025_05, n = 3)
    print("------------------------------------------------------------------------------")
    print("Last three records:")
    tail(apple_data_2025_05, n = 3)
    

    ผลลัพธ์:

    First three records:
               AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
    2025-05-01    209.08    214.56   208.90     213.32    57365700      213.0406
    2025-05-02    206.09    206.99   202.16     205.35   101010600      205.0811
    2025-05-05    203.10    204.10   198.21     198.89    69018500      198.6295
    ------------------------------------------------------------------------------
    Last three records:
               AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
    2025-05-28    200.59    202.73   199.90     200.42    45339700        200.42
    2025-05-29    203.58    203.81   198.51     199.95    51396800        199.95
    2025-05-30    199.37    201.96   196.78     200.85    70819900        200.85
    

    Note: ตลาดหุ้นวันสุดท้ายของเดือนพฤษภาคม 2025 คือ 30 พฤษภาคม ทำให้ข้อมูลสิ้นสุด ณ วันที่ 30


    2️⃣ Advanced: Set Defaults

    จะเห็นว่า getSymbols() การตั้งค่าที่หลากหลาย

    ทั้งนี้ quantmod มี 6 functions ที่ใช้ร่วมกับ getSymbols() เพื่อช่วยลดขั้นตอนในการตั้งค่าต่าง ๆ ได้แก่:

    1. getDefaults() และ setDefaults()
    2. getSymbolLookup() และ setSymbolLookup()
    3. saveSymbolLookup() และ loadSymbolLookup()

    เราไปดูวิธีการใช้งานทั้ง 6 functions กัน

    .

    🌍 getDefaults(), setDefaults()

    getDefaults() ใช้สำหรับดูค่า default ของ getSymbols()

    ส่วน setDefaults() ใช้สำหรับกำหนดค่า default

    ยกตัวอย่างเช่น เราต้องการกำหนด:

    • src จาก "yahoo" เป็น "FRED"
    • auto.assign จาก TRUE เป็น FALSE

    เราสามารถทำได้แบบนี้:

    # Get defaults before changing
    print("Defaults (before):")
    getDefaults(getSymbols)
    
    # Set defaults
    setDefaults(getSymbols,
                src = "FRED",
                auto.assign = FALSE)
     
    # Get defaults after changing
    print("Defaults (after):")
    getDefaults(getSymbols)
    

    ผลลัพธ์:

    Defaults (before):
    NULL
    
    Defaults (after):
    $src
    [1] "'FRED'"
    
    $auto.assign
    [1] FALSE
    

    ตอนนี้ ถ้าเราเรียกใช้ getSymbols() โดยไม่กำหนด src และ auto.assign ทั้งสอง arguments นี้จะเป็น "FRED" และ FALSE ตามลำดับ

    ถ้าเราต้องการ reset ค่า default ให้เราใส่ NULL ใน setDefaults():

    # Reset defaults
    setDefaults(getSymbols,
                src = NULL,
                auto.assign = NULL)
    
    # Check defaults after resetting
    print("Defaults (reset):")
    getDefaults(getSymbols)
    

    ผลลัพธ์:

    Defaults (reset):
    NULL
    

    .

    💹 setSymbolLookup(), getSymbolLookup()

    getSymbolLookup() และ setSymbolLookup() ทำงานเหมือนกับ getDefaults() และ setDefaults() แต่เป็นการตั้งค่า default สำหรับข้อมูลแต่ละตัว (แทนระดับ global) ภายใน session เท่านั้น

    ยกตัวอย่างเช่น เราต้องการกำหนดให้ดึงข้อมูลหุ้น Google มาจาก Google Finance:

    # Set default for Google
    setSymbolLookup(GOOG = list(src = "google"))
    
    # Get new defaults
    getSymbolLookup()
    

    ผลลัพธ์:

    $GOOG
    $GOOG$src
    [1] "google"
    

    Note: Google Finance หยุดให้ข้อมูลกับ quantmod เมื่อปี 2018 ทำให้ตอนนี้ เราไม่สามารถใช้ src = "google" ได้อีก

    เราสามารถ reset ค่า default ได้โดยใส่ NULL เหมือนเดิม:

    # Reset defaults
    setSymbolLookup(NULL)
    
    # Get defaults after resetting
    getSymbolLookup()
    

    ผลลัพธ์:

    named list()
    

    .

    💾 saveSymbolLookup(), loadSymbolLookup()

    ค่าที่เราใช้ setSymbolLookup() กำหนดจะถูก reset ทุกครั้งที่เราปิด session ไป

    ถ้าเราต้องการเก็บค่าเพื่อไปใช้ใน session อื่น เราสามารถใช้ saveSymbolLookup() และ loadSymbolLookup() ช่วยได้:

    • saveSymbolLookup() บันทึกค่าเก็บไว้ในไฟล์ RDS
    • loadSymbolLookup() โหลดค่าที่เก็บไว้ใน RDS

    ตัวอย่าง code:

    # Save defaults
    saveSymbolLookup(file = "symbols.rds")
    
    # Load defaults
    loadSymbolLookup(file = "symbols.rds")
    

    3️⃣ View Columns

    หลังจากเราโหลดข้อมูลมาแล้ว เราสามารถดูข้อมูลแต่ละ column ได้ด้วย 7 functions หลัก ดังนี้:

    No.FunctionFor
    1Op()ราคาเปิด
    2Hi()ราคาสูงสุด
    3Lo()ราคาต่ำสุด
    4Cl()ราคาปิด
    5Ad()ราคาปรับปรุง
    6Vo()ปริมาณการซื้อขาย
    7OHLC()ราคาเปิด, สูงสุด, ต่ำสุด, และราคาปิด

    ตัวอย่างเช่น ดูราคาเปิด:

    # Get opening price
    Op(AAPL)
    

    ผลลัพธ์:

                AAPL.Open
    2007-01-03   3.081786
    2007-01-04   3.001786
    2007-01-05   3.063214
    2007-01-08   3.070000
    2007-01-09   3.087500
    2007-01-10   3.383929
    2007-01-11   3.426429
    2007-01-12   3.378214
    2007-01-16   3.417143
    2007-01-17   3.484286
           ...           
    2025-06-05 203.500000
    2025-06-06 203.000000
    2025-06-09 204.389999
    2025-06-10 200.600006
    2025-06-11 203.500000
    2025-06-12 199.080002
    2025-06-13 199.729996
    2025-06-16 197.300003
    2025-06-17 197.199997
    2025-06-18 195.940002
    

    ดูราคาสูงสุด:

    # Get highest price
    Hi(AAPL)
    

    ผลลัพธ์:

                AAPL.High
    2007-01-03   3.092143
    2007-01-04   3.069643
    2007-01-05   3.078571
    2007-01-08   3.090357
    2007-01-09   3.320714
    2007-01-10   3.492857
    2007-01-11   3.456429
    2007-01-12   3.395000
    2007-01-16   3.473214
    2007-01-17   3.485714
           ...           
    2025-06-05 204.750000
    2025-06-06 205.699997
    2025-06-09 206.000000
    2025-06-10 204.350006
    2025-06-11 204.500000
    2025-06-12 199.679993
    2025-06-13 200.369995
    2025-06-16 198.690002
    2025-06-17 198.389999
    2025-06-18 197.570007
    

    ดูราคาต่ำสุด:

    # Get lowest price
    Lo(AAPL)
    

    ผลลัพธ์:

                 AAPL.Low
    2007-01-03   2.925000
    2007-01-04   2.993571
    2007-01-05   3.014286
    2007-01-08   3.045714
    2007-01-09   3.041071
    2007-01-10   3.337500
    2007-01-11   3.396429
    2007-01-12   3.329643
    2007-01-16   3.408929
    2007-01-17   3.386429
           ...           
    2025-06-05 200.149994
    2025-06-06 202.050003
    2025-06-09 200.020004
    2025-06-10 200.570007
    2025-06-11 198.410004
    2025-06-12 197.360001
    2025-06-13 195.699997
    2025-06-16 196.559998
    2025-06-17 195.210007
    2025-06-18 195.070007
    

    ดูราคาปิด:

    # Get closing price
    Cl(AAPL)
    

    ผลลัพธ์:

               AAPL.Close
    2007-01-03   2.992857
    2007-01-04   3.059286
    2007-01-05   3.037500
    2007-01-08   3.052500
    2007-01-09   3.306071
    2007-01-10   3.464286
    2007-01-11   3.421429
    2007-01-12   3.379286
    2007-01-16   3.467857
    2007-01-17   3.391071
           ...           
    2025-06-05 200.630005
    2025-06-06 203.919998
    2025-06-09 201.449997
    2025-06-10 202.669998
    2025-06-11 198.779999
    2025-06-12 199.199997
    2025-06-13 196.449997
    2025-06-16 198.419998
    2025-06-17 195.639999
    2025-06-18 196.580002
    

    ดูราคาปรับปรุง:

    # Get adjusted price
    Ad(AAPL)
    

    ผลลัพธ์:

               AAPL.Adjusted
    2007-01-03      2.518541
    2007-01-04      2.574442
    2007-01-05      2.556109
    2007-01-08      2.568732
    2007-01-09      2.782116
    2007-01-10      2.915256
    2007-01-11      2.879192
    2007-01-12      2.843727
    2007-01-16      2.918261
    2007-01-17      2.853645
           ...              
    2025-06-05    200.630005
    2025-06-06    203.919998
    2025-06-09    201.449997
    2025-06-10    202.669998
    2025-06-11    198.779999
    2025-06-12    199.199997
    2025-06-13    196.449997
    2025-06-16    198.419998
    2025-06-17    195.639999
    2025-06-18    196.580002
    

    ดูปริมาณการซื้อขาย:

    # Get volume
    Vo(AAPL)
    

    ผลลัพธ์:

               AAPL.Volume
    2007-01-03  1238319600
    2007-01-04   847260400
    2007-01-05   834741600
    2007-01-08   797106800
    2007-01-09  3349298400
    2007-01-10  2952880000
    2007-01-11  1440252800
    2007-01-12  1312690400
    2007-01-16  1244076400
    2007-01-17  1646260000
           ...            
    2025-06-05    55126100
    2025-06-06    46607700
    2025-06-09    72862600
    2025-06-10    54672600
    2025-06-11    60989900
    2025-06-12    43904600
    2025-06-13    51447300
    2025-06-16    43020700
    2025-06-17    38856200
    2025-06-18    45350400
    

    ดูราคาเปิด, สูงสุด, ต่ำสุด, และราคาปิด:

    # Get all price
    OHLC(AAPL)
    

    ผลลัพธ์:

                AAPL.Open  AAPL.High   AAPL.Low AAPL.Close
    2007-01-03   3.081786   3.092143   2.925000   2.992857
    2007-01-04   3.001786   3.069643   2.993571   3.059286
    2007-01-05   3.063214   3.078571   3.014286   3.037500
    2007-01-08   3.070000   3.090357   3.045714   3.052500
    2007-01-09   3.087500   3.320714   3.041071   3.306071
    2007-01-10   3.383929   3.492857   3.337500   3.464286
    2007-01-11   3.426429   3.456429   3.396429   3.421429
    2007-01-12   3.378214   3.395000   3.329643   3.379286
    2007-01-16   3.417143   3.473214   3.408929   3.467857
    2007-01-17   3.484286   3.485714   3.386429   3.391071
           ...                                            
    2025-06-05 203.500000 204.750000 200.149994 200.630005
    2025-06-06 203.000000 205.699997 202.050003 203.919998
    2025-06-09 204.389999 206.000000 200.020004 201.449997
    2025-06-10 200.600006 204.350006 200.570007 202.669998
    2025-06-11 203.500000 204.500000 198.410004 198.779999
    2025-06-12 199.080002 199.679993 197.360001 199.199997
    2025-06-13 199.729996 200.369995 195.699997 196.449997
    2025-06-16 197.300003 198.690002 196.559998 198.419998
    2025-06-17 197.199997 198.389999 195.210007 195.639999
    2025-06-18 195.940002 197.570007 195.070007 196.580002
    

    4️⃣ Visualise Data

    สุดท้าย เราสามารถสร้างกราฟเพื่อสำรวจข้อมูล โดยใช้ 2 functions ได้แก่:

    1. autoplot() จาก ggplot2 package
    2. chartSeries() จาก quantmod package

    ยกตัวอย่างเช่น สำรวจราคาปิดของ Apple:

    # Import ggplots
    library(ggplot2)
    
    # Visualise with autoplot()
    autoplot(Cl(AAPL),
             ts.colour = "darkgreen") +
    
      # Add text
      labs(title = "AAPL Closing Price (Jan 2007 – Jun 2025)",
           x = "Time",
           y = "Price (USD)")
    

    ผลลัพธ์:

    # Visualise with chartSeries()
    chartSeries(Cl(AAPL))
    

    ผลลัพธ์:


    💪 Summary

    ในบทความนี้ เราได้ดูวิธีการทำงานกับ getSymbols() เพื่อโหลดข้อมูลจากการเงินจากแหล่งต่าง ๆ กัน

    ตอนนี้ เรารู้จักกับ 5 parametres หลักของ getSymbols():

    1. Symbols
    2. src
    3. auto.assign
    4. env
    5. from และ to

    วิธีตั้งค่า default ด้วย 3 คู่ functions:

    1. getDefaults() และ setDefaults()
    2. getSymbolLookup() และ setSymbolLookup()
    3. saveSymbolLookup() และ loadSymbolLookup()

    วิธีดูข้อมูลด้วย 7 functions:

    1. Op()
    2. Hi()
    3. Lo()
    4. Cl()
    5. Ad()
    6. Vo()
    7. OHLC()

    และสุดท้าย วิธีสร้างกราฟด้วย 2 functions:

    1. autoplot()
    2. chartSeries()

    😺 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:

  • Building Wealth: สรุป 5 กลุ่มแนวคิดในการสร้างความมั่งคั่ง (Wealth) อย่างยั่งยืน จากหนังสือ The Almanack of Naval Ravikant โดย Eric Jorgenson — What Is Wealth, How to Build Wealth, What to Build Wealth With, Why Seek Wealth, และข้อคิดอื่น ๆ

    Building Wealth: สรุป 5 กลุ่มแนวคิดในการสร้างความมั่งคั่ง (Wealth) อย่างยั่งยืน จากหนังสือ The Almanack of Naval Ravikant โดย Eric Jorgenson — What Is Wealth, How to Build Wealth, What to Build Wealth With, Why Seek Wealth, และข้อคิดอื่น ๆ

    Naval Ravikant เป็นนักลงทุนชาวอเมริกันที่ประสบความสำเร็จจากการลงทุนในบริษัทอย่าง Uber, FourSquare, และ Twitter (X) และเป็น CEO ของ AngelList บริษัทที่เชื่อม startup กับ angel investor

    หนังสือ The Almanack of Naval Ravikant โดย Eric Jorgenson รวบรวมข้อคิดเกี่ยวกับความมั่งคั่ง (wealth) และความสุข (happiness) ผ่านการสัมภาษณ์และ tweet ของ Naval

    ในบทความนี้ เราจะมาสรุปเนื้อหา Building Wealth ซึ่งเป็นบทแรกจาก 5 บทในหนังสือ และพูดถึงเรื่องการสร้างความมั่งคั่งอย่างยั่งยืน

    บทความนี้แบ่งออกเป็น 5 ส่วน ได้แก่:

    1. Intro to wealth
    2. How to build wealth right
    3. What to build wealth with
    4. Why seek wealth?
    5. Additional tips on life of wealth

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


    หน้าปกหนังสือ The Alamack of Naval Ravikant บน Amazon

    1. 🏦 1. Intro to Wealth
    2. 😎 2. How to Build Wealth Right
      1. 🎁 2.1 Productise Yourself
      2. 🧠 2.2 Earn With Mind, Not Time
      3. 🎲 2.3 Luck
    3. 🏗️ 3. What to Build Wealth With
      1. ⚡ 3.1 Specific Knowledge
      2. 🧰 3.2 Leverage
      3. 🫡 3.3 Accountability
      4. 🏪 3.4 Equity
      5. 🪙 3.5 Compound Interest
    4. 🕊️ 4. Why Seek Wealth?
    5. 💡 5. Additional Tips on Life of Wealth
      1. ⌚ 5.1 Value Your Time
      2. 🚨 5.2 Avoid Ruin
      3. 🏆 5.3 Early Success
    6. 💰 Summary
    7. 🔥 Get The Almanack of Naval Ravikant

    🏦 1. Intro to Wealth

    Seek wealth, not money or status.

    — Naval Ravikant

    เราควรมองหา wealth ไม่ใช่ money หรือ status

    • Wealth = asset ที่สร้างรายได้ให้เราในขณะที่กำลังหลับ
    • Money = สื่อที่เราใช้เคลื่อนย้าย wealth
    • Status = สถานะทางสังคมที่บอกว่า เราอยู่สูงหรือต่ำขนาดไหน

    Why not money?

    Money สร้างความสุขให้เราไม่ได้ สิ่งเดียวที่ money แก้ได้ คือ ช่วยจัดการอุปสรรคที่ขัดขวางเส้นทางสู่ความสุขของเรา

    Money ทำให้เรามีกินมีใช้และสามารถใช้จ่ายในสิ่งที่เราต้องการได้ แต่สิ่งเหล่านี้ไม่ได้ใช่ความสุขที่เราตามหา

    Why not status?

    การต่อสู้เพื่อ status (อย่างการเล่นการเมือง) เป็น zero-sum game นั่นคือ ต้องมีฝ่ายแพ้และฝ่ายชนะ (-1, +1) ทำให้ในภาพรวม ไม่มีอะไรที่เปลี่ยนแปลงไปในทางที่ดีขึ้น

    ความสัมพันธ์ที่ดีควรเป็น win-win ที่ทุกฝ่ายได้ผลประโยชน์ร่วมกันในระยะยาว

    Why wealth?

    Wealth สามารถสร้างรายได้ให้เราได้ในระยะยาว เพราะ wealth สามารถทำรายได้ให้กับเราแม้ในขณะที่เรากำลังหลับ

    เราควรมองหา wealth เช่น โรงงาน ธุรกิจ หนังสือ โค้ด มากกว่า money และ status


    😎 2. How to Build Wealth Right

    แนวทางการสร้าง wealth อย่างยั่งยืนมีอยู่ 3 ข้อ ได้แก่:

    1. Productise yourself
    2. Earn with mind, not time
    3. Luck

    .

    🎁 2.1 Productise Yourself

    Productize Yourself

    — Naval Ravikant

    Productise yourself หมายถึง การพัฒนาตัวให้เป็น product ที่เป็นที่ต้องการของสังคม

    เราจะ productise ตัวเองได้สำเร็จเมื่อเราสามารถสร้างสิ่งที่:

    1. มีเอกลักษณ์เฉพาะตัว (unique/authentic)
    2. เป็นสิ่งที่สังคมต้องการ แต่ไม่รู้จะหามาได้ยังไง (เพราะถ้าหาได้ สังคมจะไม่ต้องการเรา)

    เมื่อเราสามารถทำ 2 อย่างนี้ได้ สังคมก็จะตอบแทนเรา (ด้วยเงิน)

    .

    🧠 2.2 Earn With Mind, Not Time

    Earn with your mind, not your time.

    — Naval Ravikant

    เราควรหารายได้ด้วยความคิด (mind) ไม่ใช่เวลา (time)

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

    การผูกรายได้กับเวลา หมายถึง เราจะต้องใช้เวลาแลกกับรายได้ และเราจะไม่มีรายได้ถ้าเราไม่มีเวลา

    เช่น เราจะได้เงินเดือนก็ต่อเมื่อเราทำงานครบ 1 เดือน และถ้าเดือนนั้นเราขาดงาน รายได้ของเราก็จะหายไป 1 เดือน

    Time -> Money
    Time -> Money

    หนทางในการสร้างความมั่นคง คือ เราจะต้องแยกรายได้ออกจากเวลา และหารายได้จากความคิด ไม่ใช่เวลา

    Time Mind -> Money

    ในขณะที่เวลามีอยู่อย่างจำกัด ความคิดของเราไม่มีที่สิ้นสุด และเราสามารถพัฒนาความคิดของเราให้ดีขึ้นเรื่อย ๆ ได้ ซึ่งทำให้เราสามารถหารายได้มากขึ้นเรื่อย ๆ ได้

    เมื่อเราหารายได้ด้วยความคิด ไม่ใช่เวลา รายได้ของเราจะไม่ถูกจำกัดอีกต่อไป

    Earn with your mind, not your time (source: The Almanack of Naval Ravikant)

    .

    🎲 2.3 Luck

    You put yourself in a position to capitalize on luck or to attract luck when nobody else created the opportunity for themselves.

    — Naval Ravikant

    Luck เป็นสิ่งที่เราควบคุมไม่ได้ และถ้าเราอยากสร้าง wealth อย่างมั่นคง เราควรตัด luck ออกจากสมการของเรา

    Naval มองว่า luck มีอยู่ 4 ประเภท:

    1. Blind luck: luck ที่เกิดขึ้นโดยความบังเอิญ เช่น ถูกหวย
    2. Luck from persistence: luck ที่เกิดจากความเพียร าจะพบ luck ประเภทนี้ได้เมื่อเราทำงานหนักหรือใส่ความพยายามไปกับสิ่งใดสิ่งหนึ่งเป็นเวลานาน
    3. Luck from spotting: luck ที่เกิดจากการที่เราพัฒนาทักษะในการสังเกตเห็นโอกาสต่าง ๆ ในชีวิต ทำให้เราพบเจอ luck ได้มากกว่าคนอื่น
    4. Luck that finds you: luck ที่เข้ามาหาเราเองเพราะเราพัฒนาตัวเองให้เป็นที่ต้องการของสังคม (productise yourself)

    Luck ประเภทสุดท้ายเป็น luck ที่คาดเดาได้มากที่สุด เพราะเป็น luck ที่เกิดจากตัวเองเรา

    ถ้าเราอยากสร้าง wealth เราควรตัด luck ออกจากสมการโดยการพัฒนาตัวเองจน luck วิ่งเข้ามาหาเราเอง


    🏗️ 3. What to Build Wealth With

    สิ่งที่เราควรมีเพื่อสร้าง wealth อย่างยั่งยืนมีอยู่ 5 อย่าง ได้แก่:

    1. Specific knowledge
    2. Leverage
    3. Accountability
    4. Equity
    5. Compound interest

    .

    ⚡ 3.1 Specific Knowledge

    No one can compete with you on being you.

    — Naval Ravikant

    Specific knowledge คือ ความรู้/ความสามารถเฉพาะตัว

    Specific knowledge เป็นสิ่งที่ทำให้เราแตกต่างจากคนอื่น และทำให้เราสามารถสร้างสิ่งที่สังคมต้องการแต่ยังไม่รู้ว่าจะหามาได้ยังไง เพราะสิ่งนั้นมีแต่เราที่รู้/ทำได้

    Specific knowledge เกิดมาจาก 3 ส่วน ได้แก่:

    1. Innate trait: ลักษณะที่ติดตัวเรามาตั้งแต่เกิด
    2. Passion: ความชอบ/ความหลงใหล
    3. Experience: ประสบการณ์ชีวิต

    What’s your specific knowledge?

    แต่ละคนมี specific knowledge ที่ไม่เหมือนใคร เราสามารถสังเกต specific knowledge ของเราได้โดยมองหาสิ่งที่:

    • เราทำสำเร็จได้ง่าย ๆ โดยแทบไม่ต้องใช้ความพยายาม
    • ดูเหมือนไม่ใช่ทักษะ แต่คนอื่นมองว่าเป็นความสามารถเฉพาะตัว
    • เรามองว่าเป็นงานอดิเรก เป็นการพักผ่อน แต่คนอื่นมองว่าเป็นงาน

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

    • ทักษะการขาย
    • ชอบเล่นเกม
    • ชอบอ่านหนังสือนิยายวิทยาศาสตร์
    • ทักษะนักสืบชีวิตที่ทำให้เรารู้เรื่องราวของคนรอบข้างได้หมด แม้จะไม่เคยมีใครบอกอะไรกับเราเลย

    How to develop your specific knowledge?

    เราสามารถพัฒนา specific knowledge ได้โดยทำตาม passion มากกว่าการทำตาม trend

    ยกตัวอย่างเช่น ถ้าเราชอบเล่นดนตรี เราควรฝึกเล่นดนตรี แทนที่จะเรียน machine learning ในยุคของ AI (เว้นว่า เราจะชอบ machine learning จริง ๆ)

    การทำตาม passion จะทำให้เราพัฒนา specific knowledge ได้ยั่งยืนกว่า เพราะในขณะที่คนอื่นล้มเลิกความพยายามไปตาม trend เราจะยังคงทำในสิ่งที่เรารักอยู่ ทำให้เราสั่งสมประสบการณ์การและความรู้ได้มากกว่าคนอื่น ๆ

    .

    🧰 3.2 Leverage

    Give me a lever long enough and a place to stand, and I will move the earth.

    — Archimedes

    Leverage คือ สิ่งที่จะขยาย impact ของเรา

    ยกตัวอย่างเช่น ถ้าสัดส่วนระหว่างความพยายามและผลลัพธ์อยู่ที่ 1:1, leverage สามารถทำให้สัดส่วนนี้กลายเป็น 1:2, 1:5, 1:10, 1:1,000, 1:10,000 ได้

    Leverage มีอยู่ 3 ประเภท ได้แก่:

    1. Labour
    2. Capital
    3. Product with no marginal cost of replication

    Labour หรือแรงงานเป็น leverage ที่เก่าแก่ที่สุด แต่ใช้งานยาก เพราะเราต้องมี leadership skill ที่ดี

    Capital หรือเงินทุน เป็น leverage ที่ scale ได้ดี แต่จัดการได้ยาก แต่ใครที่ทำได้จะได้แต้มต่อจากคนอื่นมาก

    Leverage ประเภทสุดท้าย คือ product with no marginal cost of replication

    ในขณะที่ labour และ capital เป็น permission-based leverage เพราะเราจะใช้ได้ก็ต่อเมื่อได้รับความยินยอมจากคนอื่น product with no marginal cost of replication เป็น permissionless leverage เพราะเราสามารถใช้ได้โดยไม่ต้องขอความยิมยอมจากใคร

    Product with no marginal cost of replication คือ สิ่งที่เราสามารถสร้างเพิ่มได้โดยใช้ต้นทุนแทบเป็น 0 เช่น:

    • หนังสือ
    • เพลง
    • โค้ด
    • YouTube video

    ในยุคที่เทคโนโลยีพัฒนาอย่างรวดเร็ว ทุกคนสามารถเข้าถึง product with no marginal cost of replication ทุกคนสามารถสร้าง video และ copy ไปโพสต์ตาม platform ต่าง ๆ โดยไม่เสียค่าใช้จ่ายสักบาท และทำให้ตัวเองให้เป็นที่รู้จักทั่วโลกได้ในชั่วข้ามคืนได้

    ถ้าอยากจะสร้างความมั่งคั่ง เราควรจะมี leverage ซึ่ง leverage ที่เข้าถึงได้ง่ายที่สุด คือ product with no marginal cost of replication

    .

    🫡 3.3 Accountability

    Clear accountability is important. Without accountability, you don’t have incentives.

    — Naval Ravikant

    Accountability หมายถึง ความรับผิดชอบในงานที่ทำ

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

    แม้จะมีความเสี่ยง แต่เราควรมี accountability ถ้าเราอยากสร้าง wealth เพราะเมื่อเรามี accountability เราก็จะมี credibility ซึ่งทำให้เราสามารถหา leverage อย่าง labour และ capital ได้ขึ้น

    นอกจากนี้ Naval มองว่า accountability ไม่ได้น่ากลัวอย่างที่คิด เพราะคนส่วนใหญ่จะให้อภัยเราถ้าเราทำผิดพลาด แต่แสดงความรับผิดชอบอย่างจริงใจพร้อมความพยายามที่จะแก้ไขให้ดีขึ้น

    ถ้าเราต้องการสร้าง wealth เราควรมี accountability ในสิ่งที่เราทำ

    .

    🏪 3.4 Equity

    You must own equity—a piece of a business—to gain your financial freedom.

    — Naval Ravikant

    นอกจาก specific knowledge, leverage, และ accountability แล้ว ถ้าเราต้องการจะสร้างความมั่งคั่งอย่างยั่งยืน เราจะควรมี equity ด้วย

    Equity เป็นการแสดงความเป็นเจ้าของ (ownership) ใน asset ที่สามารถสร้างรายได้ได้ เช่น:

    • product ต่าง ๆ
    • สินทรัพย์ทางปัญญา
    • ธุรกิจ

    ถ้าเราไม่มี ownership, ความพยายามและผลลัพธ์ที่เราได้จะอยู่ในสัดส่วนที่ 1:1 แต่ถ้ามี equity แล้ว เราจะสามารถเปลี่ยนสัดส่วนให้มากขึ้นได้

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

    ในทางกลับกัน ถ้าคุณหมอเปิดคลิกนิกเป็นของตัวเอง คุณหมอสามารถมีรายได้เท่าเดิมหรือมากขึ้นในเวลาที่น้อยลง เพราะคลินิกที่มีทั้งบุคลากร เงินทุน และ software (leverage ทั้ง 3 ประเภท) จะสร้างรายได้ให้กับคุณหมอ แม้ในขณะที่คุณหมอกำลังหลับ

    .

    🪙 3.5 Compound Interest

    The combination of those over a long period of time with the magic of compound interest will make you wealthy.

    — Naval Ravikant

    สุดท้าย สิ่งที่เราต้องการเพื่อสร้างความมั่งคั่ง คือ เวลา

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

    เวลาอยู่ข้างเรา ถ้าเราโฟกัสได้ถูกจุด

    99% vs 1%

    99% ของสิ่งที่เราทำเป็นความพยายามที่เสียเปล่า

    ยกตัวอย่างเช่น เราใช้เวลาเกือบครึ่งชีวิตไปกับการเรียน การอ่านหนังสือ การสอบที่ทำให้เราได้ความรู้ที่สุดท้ายเราไม่ได้นำมาใช้จริง

    มีเพียง 1% ของความพยายามทั้งหมดของเราที่จะให้ผลลัพธ์ที่เราต้องการ

    เราจะต้องใช้ความพยายาม 99% เพื่อหา 1% นี้ให้เจอ และเมื่อเจอแล้วให้เราทุ่มสุดตัวไปกับ 1% ที่ว่า เพราะ 1% นี้เป็นสิ่งที่ตอบโจทย์ในชีวิตของเรา

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

    Compound interest in life

    Compound interest เป็นแนวคิดทางการเงินที่ไม่ได้ใช้ได้กับการเงิน แต่ใช้กับด้านอื่น ๆ ของชีวิตอีกด้วย

    Compound interest คือ การที่เราได้ดอกเบี้ยเงินฝากเพิ่มขึ้นทุกปี เพราะในแต่ละปี เงินต้นของเราจะเท่ากับเงินต้น + ดอกเบี้ย ทำให้ดอกเบี้ยในแต่ละปีจะคิดต่อยอดจากดอกเบี้ยปีก่อน ๆ ด้วย

    Compound interest สามารถปรับใช้กับด้านต่าง ๆ ของชีวิตได้ เช่น ความสัมพันธ์

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

    การสร้าง wealth ก็เช่นกัน เมื่อเราลงทุนได้ถูกจุดแล้ว เราก็พร้อมให้ wealth สั่งสมตัวเอง และเมื่อถึงจุดหนึ่ง เราก็จะมี wealth อย่างที่เราต้องการ


    🕊️ 4. Why Seek Wealth?

    When you’re finally wealthy, you’ll realize it wasn’t what you were seeking in the first place.

    — Naval Ravikant

    ถึงตอนนี้ เราได้เห็นแนวคิดและวิธีการสร้าง wealth แล้ว แต่เรายังไม่ได้ตอบคำถามที่ว่า ทำไมเราต้องการ wealth?

    แต่ละคนอาจมีเป้าหมายในการมองหา wealth ไม่เหมือนกัน แต่ Naval เชื่อว่า เราตามหา wealth เพื่อ freedom

    Freedom ในมุมมองของ Naval คือ อิสระในทุก ๆ ด้าน เช่น:

    • อิสระในการเลือก: สามารถเลือกทำในสิ่งที่ต้องการ และไม่ทำในสิ่งที่ไม่ต้องการได้
    • อิสระในทางการเงิน: สามารถใช้จ่ายในสิ่งที่ต้องการได้
    • อิสระทางอารมณ์: ไม่ต้องมีความรู้สึกที่ทำลายความสงบทางจิตใจ

    Freedom เป็นเป้าหมายปลายทาง และ wealth เป็นเพียงทางที่จะนำเราไปสู่ freedom

    ตราบใดที่ wealth ยังสร้าง freedom ให้เรา wealth คือทางออก

    แต่เมื่อไรที่ wealth ขัดขวาง freedom ของเรา wealth คือปัญหา


    💡 5. Additional Tips on Life of Wealth

    3 คำแนะนำเพิ่มเติมจาก Naval เกี่ยวกับการใช้ชีวิตอย่างมั่งคั่ง:

    1. Value your time
    2. Avoid ruin
    3. Early success

    .

    ⌚ 5.1 Value Your Time

    Value your time at an hourly rate, and ruthlessly spend to save time at that rate.

    — Naval Ravikant

    เวลาเป็นสิ่งที่มีค่ามากที่สุดของเรา และเราควรจะใช้เวลาอย่างคุ้มค่าที่สุด

    เทคนิคหนึ่งในการจัดการเวลา คือ กำหนด hourly rate

    Hourly rate คือ ราคาค่าตัวต่อชั่วโมงของเรา เราควรตั้ง hourly rate ให้สูงจนน่าตกใจเพื่อที่:

    1. เราจะมีแรงผลักที่จะมุ่งไปข้างหน้า
    2. เราจะรู้จักใช้เวลาอย่างคุ้มค่า

    ยกตัวอย่างเช่น เราตั้ง hourly rate ไว้ที่ 5,000 บาท และถ้าเรากำลังจะใช้เวลา 1 ชั่วโมงไปกับการดู Netflix แสดงว่า เรากำลังจะเสียเงิน 5,000 บาทไปฟรี ๆ เพราะในเวลา 1 ชั่วโมง เราสามารถทำกิจกรรมอื่นที่อาจสร้างรายได้ 5,000 บาทได้

    การตั้ง hourly rate จะช่วยให้เราคำนึงถึงเวลาในการตัดสินใจต่าง ๆ ของเรา และทำให้เราใช้เวลาอย่างคุ้มค่าที่สุด

    .

    🚨 5.2 Avoid Ruin

    The one thing you have to avoid is the risk of ruin.

    — Naval Ravikant

    เราควรหลีกเลี่ยง ruin หรือสิ่งที่จะทำลายชีวิตของเรา เช่น:

    1. Jail: ไม่ทำอะไรที่ผิดกฎหมาย ไม่มีอะไรที่คุ้มค่าพอจะให้เราเข้าไปนอนในคุก
    2. Catastrophic loss: หลีกเลี่ยงการสูญเสียแบบหมดตัว เช่น การเล่นพนัน
    3. Physical danger: อันตรายต่อร่างกายและสุขภาพ

    .

    🏆 5.3 Early Success

    Some of the most successful people I’ve seen in Silicon Valley had breakouts very early in their career.

    — Naval Ravikant

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

    สำหรับคนที่เพิ่งเริ่มต้นชีวิต Naval แนะนำให้ตัดสินใจ 3 อย่างนี้ให้ดี:

    1. Where: เราจะใช้ชีวิตอยู่ที่ไหน สถานที่ที่เราอยู่จะส่งผลต่อแนวทางและเส้นทางชีวิตของเรา
    2. Who: เราจะใช้เวลาไปกับใคร หรือใครที่เราจะมีความสัมพันธ์ด้วย
    3. What: เราจะทำอะไร เช่น จะทำงานอะไร

    เราควรคิดถึง 3 เรื่องนี้ให้ถี่ถ้วนและใน timeframe ระยะยาว เช่น:

    1. Where: จะใช้ชีวิตในเมืองไหน 10 ปี?
    2. Who: จะคบกับใครไปทั้งชีวิต?
    3. What: จะทำงานเดิมกี่ปี 3 ปี? 5 ปี?

    เราควรวางแผนทั้ง 3 สิ่งนี้ให้ดี เพราะการตัดสินใจนี้จะกำหนดเส้นทางชีวิตที่เหลือของเรา


    💰 Summary

    ในบทความนี้ เราสรุปแนวคิดในการสร้าง wealth ในหนังสือ The Almanack of Naval Ravikant

    Intro to wealth: wealth คืออะไร?

    1. Seek wealth, not money or status: ตามมา wealth ไม่ใช่ money หรือ status. Wealth คือ asset ที่สร้างรายได้ให้เราในขณะที่เราหลับ ในขณะที่ money คือ สื่อในการเคลื่อนย้าย wealth และ status คือ สถานะทางสังคมของเรา

    How to build wealth right: แนวทางในการสร้าง wealth อย่างยั่งยืน

    1. Productise yourself: สร้างสิ่งที่สังคมต้องการ แต่ยังไม่รู้ว่าจะหามาได้ยังไง
    2. Earn with mind, not time: สร้างรายได้ผ่านความคิด ไม่ใช่เวลา
    3. Luck: ตัด luck ออกจากสมการสร้าง wealth ด้วยการพัฒนาตัวเองจน luck เข้ามาหาเอง

    What to build wealth with: สิ่งที่เราควรมีเพื่อสร้าง wealth อย่างยั่งยืน

    1. Specific knowledge: ความรู้/ความสามารถเฉพาะตัว
    2. Leverage: สิ่งที่จะขยาย impact ของสิ่งที่เราทำ
    3. Accountability: ความรับผิดชอบในสิ่งที่เราทำ
    4. Equity: ownership ใน asset ที่ช่วยสร้างรายได้ในขณะที่เราหลับ
    5. Compound interest: เวลา

    Why seek wealth?

    1. Freedom: เราตามหา wealth เพื่อ freedom ในชีวิต

    Additional tips: ข้อคิดเพิ่มเติมในการสร้าง wealth

    1. Value your time: กำหนด hourly rate เพื่อรู้จักใช้เวลาอย่างคุ้มค่า
    2. Avoid ruin: หลีกเลี่ยงสิ่งที่จะทำลายชีวิต เช่น jail, catastrophe loss, และ physical danger
    3. Early success: เริ่มตามหาความสำเร็จแต่เนิ่น ๆ และตัดสินใจในเรื่องที่อยู่ ความสัมพันธ์ และสิ่งที่เราจะทำให้ดี

    🔥 Get The Almanack of Naval Ravikant

    สำหรับคนที่สนใจเนื้อหาของหนังสือและอยากอ่านเพิ่มเติม สามารถซื้อหนังสือได้ตาม link ด้านล่าง:

    Note: ใครที่สนใจอ่านต้นฉบับภาษาอังกฤษแบบ e-book หรือ PDF สามารถดาวน์โหลดฟรีได้ที่ navalmanack.com