Mười bốn tháng sau khi gửi bài, phản biện vòng hai yêu cầu thêm một biến kiểm soát vào mô hình chính. Bạn mở thư mục dự án và thấy phan_tich_moi.sav, phan_tich_moi_sua.sav, ban_cuoi_that.sav. Chạy lại mô hình cũ trên file nào cũng không ra đúng hệ số trong bảng 3. Đây là tình huống rất phổ biến, và nó không đòi hỏi gian lận nào: chỉ cần vài thao tác làm sạch dữ liệu bằng tay không được ghi lại.
Tái lập (reproducibility) là mức thấp nhất của độ tin cậy khoa học: cùng dữ liệu, cùng phân tích, phải ra cùng con số. Nếu chính tác giả không làm được điều đó, người khác càng không.
Ba khái niệm hay bị trộn lẫn
| Khái niệm | Dữ liệu | Phân tích | Câu hỏi |
|---|---|---|---|
| Tái lập (reproducibility) | Giống | Giống | Có ra đúng con số đã báo cáo không? |
| Độ vững (robustness) | Giống | Khác (cách xử lý hợp lý khác) | Kết luận có đổi khi thay lựa chọn phân tích không? |
| Lặp lại (replication) | Mới | Giống hoặc tương đương | Hiện tượng có xuất hiện lại ở mẫu khác không? |
Bài này tập trung vào tầng đầu tiên, vì nó hoàn toàn nằm trong tay bạn và là nền cho hai tầng còn lại.
Cấu trúc thư mục: tách thứ không được chạm vào
Một cấu trúc đơn giản dùng được cho hầu hết dự án:
- du_lieu_tho/ — dữ liệu gốc, chỉ đọc. Không bao giờ sửa file trong này.
- du_lieu_xu_ly/ — dữ liệu do mã tạo ra. Xoá cả thư mục đi thì mã phải tạo lại được.
- ma/ — các file mã đánh số theo thứ tự chạy: 01_lam_sach, 02_bien_moi, 03_mo_hinh, 04_bang_bieu.
- ket_qua/ — bảng và hình do mã xuất ra.
- README — mô tả chạy file nào trước, cần phần mềm gì.
Nguyên tắc cốt lõi: dữ liệu thô là bất khả xâm phạm, mọi thứ khác đều tạo lại được. Nếu phải sửa một giá trị nhập sai, sửa bằng một dòng mã có ghi chú, không sửa trong file gốc.
Mã thay cho thao tác chuột
Không cần bỏ SPSS hay Excel để làm việc tái lập được. Nhưng cần một bản ghi dạng văn bản cho mọi thao tác:
- Trong SPSS, bấm “Paste” thay vì “OK” để lưu cú pháp vào file .sps, rồi chạy từ file đó.
- Trong Stata, làm việc trong file .do chứ không gõ lệnh vào cửa sổ.
- Với R và Python, viết thành script hoặc tài liệu Quarto, R Markdown, Jupyter chạy từ đầu tới cuối.
- Excel là chỗ khó nhất: ít nhất ghi lại từng bước làm sạch vào một file nhật ký, và đừng dùng Excel để mở rồi lưu lại file CSV có ngày tháng hay mã gen, vì nó tự đổi định dạng.
Phép thử: xoá hết thư mục dữ liệu xử lý và kết quả, chạy lại toàn bộ mã từ đầu. Nếu ra đủ bảng biểu giống bản thảo, bạn đã đạt mức tái lập cơ bản.
Những nguồn sai lệch âm thầm
- Phiên bản gói phần mềm: một hàm đổi giá trị mặc định giữa hai phiên bản có thể làm đổi kết quả. Ghi phiên bản bằng renv trong R, file requirements hoặc môi trường conda trong Python, hoặc ít nhất in thông tin phiên bản (sessionInfo) vào cuối file kết quả.
- Số ngẫu nhiên: bootstrap, chia tập huấn luyện – kiểm tra, mô phỏng, phương pháp gán giá trị thiếu nhiều lần. Luôn đặt hạt giống (set.seed) ở đầu file và ghi nó trong bài.
- Đường dẫn tuyệt đối: “C:/Users/Lan/Desktop/…” chạy trên máy người khác sẽ hỏng ngay. Dùng đường dẫn tương đối tính từ thư mục dự án.
- Thứ tự chạy: biến tạo ở file 03 nhưng được dùng ở file 02 vì bạn chạy tay theo thứ tự khác. Chạy lại từ đầu phát hiện lỗi này.
- Làm tròn: báo cáo số đã làm tròn rồi dùng số đó để tính tiếp. Tính trên số đầy đủ, chỉ làm tròn khi trình bày.
Quản lý phiên bản không cần thành lập trình viên
Git có đường học dốc, nhưng chỉ cần ba việc: lưu một “ảnh chụp” (commit) mỗi khi mã chạy được, viết một dòng mô tả đã đổi gì, và đẩy lên một kho riêng tư. Các ứng dụng giao diện đồ hoạ hoặc tính năng Git có sẵn trong RStudio, VS Code làm việc này bằng vài cú bấm. Lợi ích lớn nhất: bạn biết chính xác mã nào đã sinh ra bảng trong bản thảo gửi ngày nào.
Nếu Git vẫn là quá nhiều, tối thiểu hãy nén thư mục mã kèm ngày mỗi khi gửi bản thảo hoặc bản chỉnh sửa, và lưu cùng thư phản hồi phản biện.
Tài liệu động: số trong bài sinh ra từ mã
Quarto và R Markdown cho phép viết văn bản xen với mã, nên con số trong câu “hệ số hồi quy là 0,34” được lấy thẳng từ kết quả chạy. Không còn cảnh sửa mô hình xong quên cập nhật một con số ở phần thảo luận. Nếu tạp chí yêu cầu file Word, các công cụ này xuất được sang Word.
Kiểm tra tái lập trước khi nộp
- Chạy toàn bộ mã trên một máy khác hoặc một tài khoản sạch.
- So từng con số trong bảng và trong văn bản với kết quả mã xuất ra; đánh dấu từng số đã kiểm.
- Nhờ một đồng nghiệp chỉ đọc README rồi chạy thử. Đo xem mất bao lâu và vấp ở đâu.
- Đóng gói phiên bản gửi đi (mã, dữ liệu đã ẩn danh nếu được phép, README) và lưu lên kho có DOI hoặc kho riêng tư kèm ngày.
Một số tạp chí đã có biên tập viên dữ liệu (data editor) chạy lại mã trước khi đăng. Làm bước kiểm tra này trước giúp bạn không bị trả bài vì lý do kỹ thuật.
Làm gì với dự án cũ đang dở dang
Không cần làm lại tất cả. Chọn bảng kết quả chính, viết mã tái tạo đúng bảng đó từ dữ liệu thô, và dừng ở đó. Với các phân tích phụ, ghi lại những gì bạn nhớ vào README. Tái lập được một nửa vẫn tốt hơn không tái lập được gì.
Việc nên làm ngay: tạo thư mục du_lieu_tho, chép dữ liệu gốc vào, đặt quyền chỉ đọc cho nó. Riêng bước này đã loại bỏ nguồn lỗi phổ biến nhất, đó là vô tình ghi đè lên dữ liệu gốc.
Câu hỏi thường gặp
Tái lập và lặp lại nghiên cứu khác nhau thế nào?
Tái lập là dùng đúng dữ liệu và phân tích cũ để ra lại con số đã báo cáo. Lặp lại là làm nghiên cứu mới với dữ liệu mới để xem hiện tượng có xuất hiện lại không.
Dùng SPSS có tái lập được không?
Được, nếu bạn lưu cú pháp bằng nút Paste và chạy phân tích từ file cú pháp thay vì bấm menu. File cú pháp chính là bản ghi mọi thao tác.
Vì sao cần đặt set.seed?
Các phương pháp dùng số ngẫu nhiên như bootstrap hay mô phỏng sẽ cho kết quả hơi khác mỗi lần chạy. Đặt hạt giống giúp ra đúng một kết quả mỗi lần chạy lại.
Có phải học Git mới làm được nghiên cứu tái lập không?
Không bắt buộc. Git giúp nhiều, nhưng mức tối thiểu là mã chạy từ đầu tới cuối, dữ liệu thô không bị sửa và lưu bản mã kèm ngày mỗi lần gửi bài.
Làm sao ghi lại phiên bản gói R hoặc Python đã dùng?
Trong R dùng renv hoặc in sessionInfo; trong Python dùng file requirements hoặc môi trường conda. Lưu thông tin này cùng mã phân tích.