HocThuatSo.comHọc Thuật Số
Gửi thư
R cho nghiên cứu

Nhập dữ liệu SPSS, Stata, Excel vào R mà giữ nguyên nhãn biến

Dùng haven và readxl để đọc tệp .sav, .dta, .xlsx vào R mà không mất nhãn biến, nhãn giá trị, giá trị thiếu do người dùng định nghĩa, và không vỡ tiếng Việt.

Nhập dữ liệu SPSS, Stata, Excel vào R mà giữ nguyên nhãn biến

Để nhập dữ liệu SPSS, Stata vào R mà giữ nhãn, dùng gói haven (read_sav(), read_dta()); với Excel, dùng readxl::read_excel(). Nhãn biến và nhãn giá trị được giữ trong thuộc tính của cột, chỉ chuyển sang factor khi thật sự cần, và đọc mã thiếu do người dùng định nghĩa bằng user_na = TRUE.

Phần lớn dữ liệu khảo sát ở các nhóm nghiên cứu trong nước vẫn đi qua SPSS hoặc Excel trước khi tới tay người dùng R. Câu hỏi không phải là có đọc được không, mà là đọc xong còn giữ được bao nhiêu thông tin: câu hỏi đầy đủ của biến q7, giá trị 1 nghĩa là “Rất không đồng ý” hay “Rất đồng ý”, và 99 là “Không trả lời” chứ không phải điểm 99.

Định dạng nào đọc bằng hàm nào?

Hai gói haven và readxl đều thuộc hệ tidyverse, cài riêng bằng install.packages():

TệpHàmGiữ được gìĐiểm cần nhớ
SPSS .sav, .zsavhaven::read_sav()Nhãn biến, nhãn giá trị, mã thiếu (khi bật user_na)Tệp SPSS cũ không ở chế độ Unicode có thể cần tham số encoding
SPSS .porhaven::read_por()Nhãn biến, nhãn giá trịĐịnh dạng cũ, ít gặp
Stata .dtahaven::read_dta()Nhãn biến, nhãn giá trị, giá trị thiếu mở rộng .a đến .zThiếu mở rộng thành NA có gắn thẻ
SAS .sas7bdathaven::read_sas()Nhãn biến; định dạng giá trị nằm ở tệp catalog riêngCần cả tệp catalog nếu muốn nhãn giá trị
Excel .xlsx, .xlsreadxl::read_excel()Giá trị ô, kiểu ôKhông có khái niệm nhãn, phải lấy từ bảng mã
CSV xuất từ Excelreadr::read_csv()Chỉ giá trịPhải đúng bảng mã ký tự

Nhãn trong haven hoạt động thế nào?

Cột có nhãn là kiểu labelled

Sau d <- haven::read_sav(here::here('du-lieu', 'tho', 'khaosat.sav')), cột gioi có kiểu haven_labelled: giá trị vẫn là số 1, 2, còn nhãn “Nam”, “Nữ” nằm trong thuộc tính. In bảng ra, bạn thấy dạng 1 [Nam]. Nhãn biến (câu hỏi đầy đủ) nằm ở thuộc tính label, xem bằng labelled::var_label(d$gioi), hoặc tìm biến theo từ khoá trong câu hỏi bằng labelled::look_for(d, 'thu nhập').

Khi nào đổi sang factor

Hàm thống kê không hiểu nhãn, nên trước khi đưa biến phân loại vào mô hình hay bảng, đổi bằng haven::as_factor(). Tham số levels chọn lấy nhãn, lấy giá trị hay cả hai. Lưu ý: as_factor() giữ cả nhãn không ai chọn, nên bảng tần số có thể hiện một dòng 0; thêm droplevels() nếu không muốn dòng đó.

Biến thang đo Likert dùng làm điểm số thì đừng đổi sang factor. Dùng haven::zap_labels() để bỏ nhãn, giữ số.

Giá trị thiếu do người dùng định nghĩa xử lý ra sao?

Mặc định: biến thành NA

Trong SPSS, người nhập liệu hay khai 99 hoặc 9 là thiếu. read_sav() mặc định đổi các giá trị đó thành NA luôn. Tiện, nhưng mất thông tin “không trả lời” khác “không áp dụng”.

Giữ lại bằng user_na

Gọi read_sav(tep, user_na = TRUE), cột thành kiểu haven_labelled_spss, giá trị 99 còn nguyên, và is.na() vẫn trả TRUE cho nó. Khi cần phân tích lý do thiếu, đếm theo từng mã; khi chạy mô hình, gọi haven::zap_missing() để đổi hết thành NA.

Stata: thiếu có gắn thẻ

.a, .b trong Stata được đọc thành NA có thẻ. Hàm haven::na_tag() cho biết thẻ của từng ô, đủ để phân biệt “từ chối trả lời” với “không biết”.

Đọc Excel có tiếng Việt và tiêu đề nhiều dòng

Tệp .xlsx lưu chữ theo Unicode nên tiếng Việt đọc vào R thường không vỡ. Rắc rối nằm ở cách người ta trình bày bảng: hai dòng tiêu đề gộp ô, dòng ghi chú ở trên cùng, ô trống để “ngầm hiểu giống dòng trên”, và các ký hiệu như “-” hoặc “KXĐ” cho ô thiếu.

read_excel() có đủ tham số để xử lý: sheet chọn trang theo tên, range = 'A3:K250' chỉ đọc vùng dữ liệu, skip bỏ dòng đầu, na = c('', '-', 'KXĐ', '99') khai các ký hiệu thiếu, col_types ép kiểu từng cột khi R đoán sai. Tiêu đề hai tầng thì đọc với col_names = FALSE rồi tự đặt tên cột theo bảng mã, thay vì cố ghép tự động.

Với CSV xuất từ Excel, chọn kiểu lưu CSV UTF-8 nếu được. Nếu nhận tệp CSV thường từ máy Windows tiếng Việt và chữ bị vỡ, thử readr::read_csv(tep, locale = readr::locale(encoding = 'windows-1258')). Kiểm lại bằng cách in vài giá trị có dấu như “Đắk Lắk”, “Thừa Thiên Huế”.

Gắn nhãn cho dữ liệu Excel từ bảng mã

Dữ liệu Excel không mang nhãn, nhưng bạn có thể tạo lại từ bảng mã biến. Với nhãn biến: labelled::var_label(d) <- list(q1 = 'Mức hài lòng với thư viện', q2 = 'Số giờ tự học mỗi tuần'). Với nhãn giá trị: d$gioi <- haven::labelled(d$gioi, c(Nam = 1, 'Nữ' = 2)).

Làm bước này trong kịch bản làm sạch, rồi lưu bằng saveRDS() ra du-lieu/xu-ly/. Định dạng .rds giữ nguyên thuộc tính nhãn. Nếu cần trả dữ liệu về cho đồng nghiệp dùng SPSS, haven::write_sav() ghi ra tệp có nhãn và mã thiếu đầy đủ; write_dta() làm tương tự cho Stata.

Ngược lại, khi nhận tệp SPSS mà không có bảng mã, bạn có thể tự sinh bảng mã từ chính tệp: labelled::look_for(d) trả về một bảng gồm vị trí, tên biến, nhãn biến, kiểu cột, số ô thiếu và nhãn giá trị. Đọc bảng này trước khi viết dòng phân tích đầu tiên giúp phát hiện sớm biến bị đảo chiều thang, biến có nhãn lạ hoặc biến thiếu gần hết. Lưu bảng đó vào tai-lieu/ để cả nhóm dùng chung.

Dữ liệu từ biểu mẫu trực tuyến cần chú ý gì?

Google Forms

Câu trả lời đổ vào Google Sheets, tải về dạng .xlsx hoặc CSV. Tiêu đề cột là nguyên văn câu hỏi, rất dài; đổi tên ngay sau khi đọc bằng một vectơ tên ngắn theo bảng mã. Câu nhiều lựa chọn được ghép vào một ô, ngăn bằng dấu phẩy, dễ lẫn với dấu phẩy trong chính phương án trả lời. Cột dấu thời gian đọc vào thường là kiểu ngày giờ, cần kiểm múi giờ.

KoboToolbox và các công cụ dùng biểu mẫu XLSForm

Khi xuất dữ liệu, có thể chọn xuất giá trị mã hay nhãn. Với R, xuất giá trị mã rồi gắn nhãn từ tệp biểu mẫu sẽ chắc hơn, vì nhãn có thể bị sửa giữa các đợt thu mà mã thì giữ nguyên.

LimeSurvey

Có lựa chọn xuất kết quả sang định dạng SPSS và R. Bản SPSS mang theo nhãn, đọc bằng read_sav() là gọn nhất.

Ngày tháng, mã số và câu nhiều lựa chọn

Ba loại cột hay hỏng nhất khi đi từ Excel vào R:

  • Ngày gõ tay kiểu Việt Nam. Ô “03/09/2025” có thể bị Excel hiểu thành ngày 9 tháng 3 nếu máy đặt định dạng Mỹ. Khi cột ngày đọc vào ở dạng chữ, đổi bằng lubridate::dmy() và đếm số ô thành NA để bắt các ô gõ sai như ngày 31 tháng 13.
  • Mã có số 0 ở đầu. Mã tỉnh, mã trường, mã sinh viên đọc thành số sẽ mất số 0 đầu. Khai col_types = 'text' cho các cột đó.
  • Câu nhiều lựa chọn. Mỗi phương án nên thành một cột 0/1. Tách ô ghép bằng tidyr::separate_longer_delim() rồi chuyển rộng; cách làm cụ thể nằm ở bài về dplyr và tidyr trong cùng chuyên mục.

Ghi mọi quyết định đổi kiểu vào kịch bản, không sửa trực tiếp trong tệp Excel gốc.

Lỗi hay gặp khi nhập và cách bắt sớm

Một tình huống quen: nhóm báo cáo tỷ lệ nữ trong mẫu lệch so với số liệu SPSS vì một bên coi 99 là thiếu, bên kia tính 99 như một nhóm. Rà nhanh mấy điểm sau ngay sau khi nhập:

  • So số dòng, số cột với SPSS hoặc Excel. Lệch dòng thường do dòng ghi chú cuối bảng.
  • In haven::print_labels(d$bien) cho vài biến then chốt để chắc chiều thang đo.
  • Đếm thiếu theo từng cột: colSums(is.na(d)). Một cột thiếu toàn bộ thường là do khai sai na hoặc sai kiểu cột.
  • Dùng dplyr::count(d, tinh) để thấy cùng một tỉnh bị gõ thành nhiều dạng.
  • Kiểm cột ngày: Excel lưu ngày dạng số, read_excel() thường nhận đúng, nhưng ô gõ tay dạng chữ sẽ đổi cả cột thành văn bản.

Việc KHÔNG cần làm: chuyển mọi tệp SPSS sang CSV trước khi đọc. Làm vậy chỉ làm mất nhãn mà haven giữ được.

Câu hỏi thường gặp

haven có đọc được tệp SPSS mới nhất không?

haven đọc được định dạng .sav và .zsav thông dụng qua thư viện ReadStat. Nếu gặp tệp không đọc được, nhờ người gửi lưu lại từ SPSS bằng tuỳ chọn định dạng thông thường rồi thử lại.

Có cần gói foreign nữa không?

Không bắt buộc. Gói foreign vẫn dùng được nhưng haven giữ nhãn và giá trị thiếu tốt hơn, trả về bảng kiểu tibble và có hàm ghi ngược ra SPSS, Stata.

Vì sao biến Likert hiện ra dạng 4 [Đồng ý]?

Đó là kiểu labelled của haven: giá trị số 4 kèm nhãn. Muốn tính trung bình, dùng zap_labels để bỏ nhãn; muốn lập bảng tần số theo nhãn, dùng as_factor.

Tiếng Việt trong tệp SPSS bị vỡ thì làm gì?

Thường do tệp lưu từ phiên bản SPSS cũ không ở chế độ Unicode. Thử tham số encoding của read_sav với bảng mã mà máy tạo tệp dùng, hoặc nhờ người gửi mở lại tệp trong SPSS ở chế độ Unicode rồi lưu.

Nên lưu dữ liệu đã làm sạch ở định dạng nào?

Để dùng tiếp trong R, lưu .rds vì giữ nguyên kiểu và nhãn. Để chia sẻ rộng hoặc nộp kho dữ liệu, xuất thêm CSV UTF-8 kèm bảng mã biến riêng.

read_excel đoán sai kiểu cột thì sửa thế nào?

Khai col_types cho từng cột, hoặc tăng guess_max để hàm xem nhiều dòng hơn khi đoán. Cột mã số như mã tỉnh nên ép kiểu text để giữ số 0 ở đầu.

Cần tư vấn cụ thể cho trường hợp của bạn?

Chúng tôi sẽ liên hệ trong vòng 24 giờ.

Đăng ký tư vấn ngay

Bài viết liên quan

🧭
Bạn đang ở chặng nào của đường học vị?
Nhập chỗ bạn đang đứng và đích bạn nhắm — công cụ trả về số năm, chi phí và việc phải làm từng chặng.
Xem lộ trình của tôi →
Miễn phí, không cần tài khoản. Xem tất cả công cụ

Bạn cần hỗ trợ thêm?

Để lại thông tin, chúng tôi sẽ liên hệ trong 24 giờ.

hoặc
[email protected]