Skip to content

↑ R2 · ← Environments & Scoping · → Joins & Grouped Ops

🎯 Mục tiêu

Tidyverse mạnh vì nó cho bạn “ngôn ngữ biến đổi dữ liệu”. Nhưng trong production, thứ bạn cần là: pipeline có contract rõ ràng và behavior ổn định qua thời gian. Bài này chốt mindset đó.

1) Tidyverse như một pipeline có hợp đồng

Một pipeline tốt luôn trả lời được 3 câu:

  • Input contract: dữ liệu vào có schema gì (cột bắt buộc, kiểu dữ liệu, keys)?
  • Transform contract: bước này làm gì, có thể thay đổi số dòng/số cột không?
  • Output contract: dữ liệu ra có schema gì và ai là consumer?

Nếu bạn không viết được contract bằng lời, rất dễ “lỡ tay” đổi shape và làm downstream sai số liệu.

1.1 Invariants nên giữ (trừ khi bạn cố ý phá)

  • Keys: khóa định danh của row (ví dụ user_id, date) không được missing/duplicate nếu bạn tuyên bố đó là key.
  • Row count: nhiều bước nên giữ số dòng (mutate, rename, relocate). Các bước phá row count phải được ghi rõ (filter, summarise, distinct, join).
  • Column semantics: cột “Date” phải còn class Date; cột “category” phải còn levels nếu bạn dùng factor; ...

✅ Checklist triển khai

Contract tối thiểu cho mỗi dataset

  • Xác định key (hoặc nói rõ “không có key”)
  • Danh sách cột bắt buộc
  • Missingness policy (cột nào cho phép NA)
  • Timezone/locale policy nếu có datetime

2) Verbs cốt lõi: đọc như một câu, không phải “ảo thuật”

Các verbs thường gặp:

  • select()/rename()/relocate() để quản lý schema
  • filter() để giảm rows
  • mutate() để thêm/đổi columns
  • arrange() để sắp xếp (đừng dựa vào thứ tự ngẫu nhiên)
  • summarise()/reframe() để giảm hoặc tái cấu trúc rows theo group
  • pivot_longer()/pivot_wider() để reshape

Mindset: mỗi verb phải trả lời “tôi đang đổi schema hay đổi số dòng?”

3) Pipeline hygiene: code phải debug được

3.1 Đặt tên trung gian khi bước phức tạp

Chain 10 bước không sai, nhưng khi nó bắt đầu chứa logic điều kiện, join, grouped ops, bạn nên “đặt checkpoint”:

  • để in ra số dòng,
  • để kiểm tra missing keys,
  • để unit test bước quan trọng.

Ví dụ (ý tưởng):

  • Sau ingest: validate schema + types
  • Sau join: validate row explosion không xảy ra
  • Trước export: validate output contract

3.2 Không để warnings trôi qua

Trong pipeline, warnings thường là signal:

  • parse fail → tạo NA mới
  • recycling/coercion → kiểu dữ liệu bị đổi

Rule: warnings phải được giải thích (fix hoặc chấp nhận có lý do và đo lường).

4) Grouped ops: khái niệm và bẫy phổ biến

group_by() tạo trạng thái “grouped data frame”. Nhiều verbs sẽ thay đổi hành vi khi object đang grouped.

4.1 Grouped state là “hidden state”

Bạn có thể đang nghĩ mình làm trên toàn bộ dataset, nhưng thực ra đang làm theo từng group.

Ví dụ bẫy:

  • mutate() trên grouped df thường tạo feature “within group”
  • slice_*() chọn top-n trong từng group

4.2 Khi grouped ops nguy hiểm

Grouped ops trở nên nguy hiểm khi:

  • bạn quên ungroup() và downstream bị apply theo group không mong muốn,
  • bạn join một dataset grouped và tạo ra behavior khó đoán,
  • bạn summarise() làm giảm rows nhưng downstream vẫn tưởng row-level.

Kỷ luật:

  • Sau khi xong “block logic theo group”, kết thúc bằng ungroup().
  • Với summarise(), luôn set .groups để behavior explicit.

Ví dụ (ý tưởng, không phụ thuộc version):

r
# summarise(..., .groups = "drop")  # explicit: drop grouping
# summarise(..., .groups = "keep")  # explicit: keep grouping

4.3 summarise() vs reframe()

Mindset correctness:

  • summarise(): thường trả 1 row/group (hoặc vài row tùy expression) → dùng khi bạn thật sự “aggregate”.
  • reframe(): dùng khi bạn muốn trả về nhiều rows/group một cách rõ ý (và chấp nhận row count thay đổi).

Nếu team bạn dùng dplyr version khác nhau, hãy thống nhất convention để tránh drift.

⚠️ Cạm bẫy

Grouped df như một “mode” của dataset. Nếu bạn không reset mode (ungroup), bạn đang để state ẩn chạy xuyên suốt pipeline.

5) Checklist: pipeline “đúng trước, nhanh sau”

✅ Checklist triển khai

Ship-ready transform

  • Validate input schema trước khi transform
  • Sau group_by(): kết thúc block bằng ungroup()
  • Sau join: kiểm tra key uniqueness và row explosion
  • Trước export: validate output schema + missingness policy