KTL cơ bảnXử lý dữ liệu

Kiểm tra dữ liệu nhập SPSS

Kiểm tra dữ liệu nhập bằng bảng tần suất Frequencies với SPSS

Tóm tắt: Kiểm tra dữ liệu nhập là bước đầu tiên và quan trọng nhất trong thực hành kinh tế lượng. Bài viết này hướng dẫn chi tiết cách sử dụng bảng tần suất Frequencies trong SPSS để phát hiện các giá trị không hợp lệ, giá trị ngoài phạm vi, và các lỗi nhập liệu thường gặp. Thông qua việc phân tích bảng Statistics và bảng tần suất từng biến, các bạn sẽ học cách xác định và xử lý các vấn đề dữ liệu để đảm bảo độ tin cậy cho các phân tích tiếp theo.

Giới thiệu về kiểm tra dữ liệu nhập

Nội dung chính

Trong thực hành kinh tế lượng, chất lượng dữ liệu là yếu tố quyết định đến độ tin cậy và tính chính xác của toàn bộ quá trình phân tích. Một bộ dữ liệu có chất lượng kém, chứa nhiều lỗi sẽ dẫn đến những kết luận sai lệch và có thể gây tổn hại nghiêm trọng đến các quyết định kinh tế.

Kiểm tra dữ liệu nhập (Data Screening) là quá trình hệ thống nhằm phát hiện và khắc phục các vấn đề về chất lượng dữ liệu trước khi tiến hành các phân tích thống kê chính thức. Đây là bước đầu tiên và bắt buộc trong mọi nghiên cứu thực hành kinh tế lượng chuyên nghiệp.

Ví dụ minh họa trong bối cảnh Việt Nam

Để hiểu rõ tầm quan trọng của việc kiểm tra dữ liệu nhập, hãy xem xét một ví dụ cụ thể từ nghiên cứu kinh tế Việt Nam. Giả sử chúng ta đang tiến hành khảo sát về mức thu nhập của các hộ gia đình tại TP.HCM với thang đo từ 1 – 5:

  • 1: Dưới 5 triệu VND/tháng
  • 2: Từ 5-10 triệu VND/tháng
  • 3: Từ 10-15 triệu VND/tháng
  • 4: Từ 15-25 triệu VND/tháng
  • 5: Trên 25 triệu VND/tháng

Trong quá trình nhập liệu, nếu phát hiện có các quan sát với giá trị thu nhập là 6, 7, hoặc 0, điều này cho thấy có lỗi trong quá trình thu thập hoặc nhập dữ liệu. Việc để lại những giá trị không hợp lệ này sẽ làm sai lệch toàn bộ kết quả phân tích về phân bố thu nhập và các mối quan hệ kinh tế.

Tầm quan trọng của việc kiểm tra dữ liệu

Việc kiểm tra dữ liệu nhập trong thực hành kinh tế lượng mang lại những lợi ích quan trọng sau:

Đảm bảo tính chính xác của phân tích

  • Phát hiện sớm các lỗi nhập liệu và giá trị ngoài phạm vi
  • Xác định các pattern bất thường trong dữ liệu
  • Ngăn ngừa việc sử dụng dữ liệu sai để đưa ra kết luận
  • Tăng độ tin cậy của các ước lượng thống kê

Tiết kiệm thời gian và chi phí

Việc phát hiện và khắc phục sớm các vấn đề về dữ liệu giúp:

  • Tránh phải thực hiện lại toàn bộ quá trình phân tích
  • Giảm thiểu rủi ro trong việc đưa ra quyết định kinh tế
  • Nâng cao hiệu quả của nghiên cứu
  • Đảm bảo tuân thủ các tiêu chuẩn nghiên cứu quốc tế

Các loại lỗi dữ liệu thường gặp

Trong thực hành kinh tế lượng, có một số loại lỗi dữ liệu phổ biến mà chúng ta cần chú ý:

Lỗi giá trị ngoài phạm vi

Đây là loại lỗi phổ biến nhất, xảy ra khi:

  • Nhập sai thang đo (ví dụ: nhập 6 thay vì 5 cho thang đo 1-5)
  • Nhầm lẫn đơn vị đo lường (triệu so với nghìn)
  • Lỗi bàn phím khi nhập liệu
  • Hiểu sai câu hỏi của người phỏng vấn

Lỗi giá trị bị thiếu

Giá trị thiếu có thể do:

  • Người được khảo sát từ chối trả lời
  • Quên không ghi nhận thông tin
  • Lỗi kỹ thuật trong quá trình thu thập
  • Mất mát dữ liệu trong quá trình truyền tải

Lỗi định dạng dữ liệu

Bao gồm các vấn đề về:

  • Kiểu dữ liệu không đúng (text thay vì number)
  • Ký tự đặc biệt trong dữ liệu số
  • Định dạng ngày tháng không nhất quán
  • Mã hóa ký tự (encoding) bị lỗi
Kiểm tra dữ liệu nhập trên SPSS
Kiểm tra dữ liệu nhập trên SPSS

Hướng dẫn thực hành chi tiết trên SPSS

Bước đầu tiên trong quy trình kiểm tra dữ liệu là sử dụng bảng tần suất Frequencies trong SPSS. Đây là công cụ mạnh mẽ giúp chúng ta có cái nhìn tổng quan về phân phối dữ liệu và phát hiện các vấn đề tiềm ẩn.

Tải về dữ liệu mẫu

Bước 1: Truy cập công cụ Frequencies

Để thực hiện phân tích tần suất trong SPSS, các bạn thực hiện theo trình tự sau:

  1. Chọn AnalyzeDescriptive StatisticsFrequencies
  2. Chuyển tất cả các biến cần kiểm tra vào cửa sổ Variable(s)
  3. Bấm OK để thực hiện phân tích
Mẹo thực hành: Nên chọn tất cả các biến cùng một lúc để có cái nhìn toàn diện về toàn bộ bộ dữ liệu. Điều này giúp tiết kiệm thời gian và dễ dàng so sánh giữa các biến.

Bước 2: Chuẩn bị dữ liệu mẫu

Để thực hành, chúng ta sử dụng file lọc quan sát – một bộ dữ liệu mẫu được thiết kế đặc biệt để minh họa các vấn đề thường gặp trong thực hành kinh tế lượng.

Tải về dữ liệu mẫu

Bước 3: Phân tích kết quả Frequencies

Sau khi thực hiện 3 bước trên, kết quả Frequencies sẽ xuất hiện dưới dạng hai bảng chính:

Bảng Statistics – Thông tin tổng quan

Bảng Statistics cung cấp thông tin tổng quan về từng biến, đặc biệt là số lượng quan sát bị thiếu (missing). Đây là thông tin quan trọng mà chúng ta sẽ sử dụng để kiểm tra missing values ở các bước tiếp theo.

Bảng Statistics hiển thị số quan sát missing của từng biến trong SPSS

Từ bảng Statistics, chúng ta có thể nhanh chóng xác định:

  • N Valid: Số quan sát có dữ liệu hợp lệ
  • N Missing: Số quan sát bị thiếu dữ liệu
  • Tỷ lệ missing: Mức độ nghiêm trọng của vấn đề dữ liệu thiếu
  • Pattern missing: Liệu có biến nào bị thiếu quá nhiều dữ liệu không

Bảng tần suất từng biến – Phân tích chi tiết

Bảng Each variable được thể hiện dưới dạng bảng tần suất của từng biến. Nó cho biết tần suất xuất hiện các giá trị của biến, giúp chúng ta phát hiện:

  • Các giá trị nằm ngoài phạm vi định nghĩa
  • Phân phối tần suất bất thường
  • Các giá trị xuất hiện quá ít hoặc quá nhiều
  • Mẫu hình (pattern) không hợp lý trong dữ liệu

Ví dụ chi tiết: Phát hiện giá trị không hợp lệ

Để minh họa cách phát hiện và xử lý giá trị không hợp lệ, chúng ta xem xét ví dụ về biến income trong bộ dữ liệu mẫu:

Bối cảnh: Biến thu nhập của người lao động được mã hóa từ 1 đến 5 tương ứng với các mức thu nhập từ dưới 5 triệu VND/tháng đến trên 25 triệu VND/tháng. Tuy nhiên, kết quả bảng tần suất cho thấy có 6 quan sát có giá trị thu nhập là 6 – một giá trị không nằm trong phạm vi định nghĩa của biến.

Đây là dấu hiệu của vấn đề dữ liệu không hợp lệ và chúng ta cần phải:

  • Xác định nguyên nhân: lỗi nhập liệu, hiểu sai câu hỏi, hay vấn đề khác
  • Tìm ra chính xác quan sát nào bị lỗi
  • Kiểm tra lại nguồn dữ liệu gốc (bảng trả lời khảo sát)
  • Quyết định cách xử lý: sửa chữa, loại bỏ, hay mã hóa lại

Bước 4: Xác định vị trí quan sát bị lỗi

Để biết chính xác quan sát nào có giá trị income bằng 6, chúng ta sử dụng chức năng tìm kiếm của SPSS:

  1. Trở về cửa sổ Data View
  2. Chọn cột (biến) income
  3. Bấm Ctrl + F (hoặc vào menu Edit → Find)
  4. Nhập giá trị 6 vào ô Find:
  5. Bấm Find Next để lần lượt dò tìm các quan sát có income bằng 6

 

Lưu ý quan trọng: Sau khi tìm thấy các quan sát bị lỗi, không nên vội vàng xóa hoặc thay đổi. Cần ghi lại vị trí của chúng và quay lại kiểm tra nguồn dữ liệu gốc để xác định cách xử lý phù hợp.

Phân tích và diễn giải kết quả

Việc phân tích kết quả từ bảng Frequencies cần được thực hiện một cách có hệ thống và toàn diện để đảm bảo không bỏ sót bất kỳ vấn đề nào.

Tiêu chí đánh giá chất lượng dữ liệu

Khi đánh giá kết quả Frequencies, chúng ta cần chú ý đến các tiêu chí sau:

  • Tỷ lệ missing: Không vượt quá 5% cho từng biến quan trọng
  • Phạm vi giá trị: Tất cả giá trị phải nằm trong khoảng định nghĩa
  • Phân phối hợp lý: Không có mục (category) nào quá ít quan sát (nhỏ hơn 5)
  • Tính nhất quán: Các biến liên quan cần có mẫu hình phù hợp

Các pattern cần chú ý

Trong thực hành kinh tế lượng, một số mẫu hình đáng ngờ bao gồm:

Pattern 1: Tập trung quá mức tại một giá trị

Nếu một giá trị xuất hiện quá nhiều (lớn hơn 90% số quan sát), có thể do:

  • Lỗi trong thiết kế bảng hỏi
  • Thiên chệch (bias) trong quá trình thu thập dữ liệu
  • Vấn đề trong cách mã hóa dữ liệu

Pattern 2: Không có quan sát tại các giá trị đầu/cuối

Điều này có thể cho thấy:

  • Thang đo không phù hợp với tổng thể nghiên cứu
  • Bias trong quá trình chọn mẫu
  • Hiện tượng ceiling/floor effect

Pattern 3: Phân phối không hợp lý

Ví dụ: Thu nhập tập trung chủ yếu ở mức cao nhất trong khảo sát về hộ nghèo

Quy trình xử lý phát hiện

Khi phát hiện vấn đề qua bảng Frequencies, quy trình xử lý nên tuân theo các bước sau:

  • Bước 1: Ghi lại tất cả các vấn đề phát hiện được
  • Bước 2: Xác định mức độ nghiêm trọng của từng vấn đề
  • Bước 3: Kiểm tra lại nguồn dữ liệu gốc
  • Bước 4: Quyết định phương án xử lý phù hợp
  • Bước 5: Thực hiện xử lý và kiểm tra lại
  • Bước 6: Ghi chép lại toàn bộ quá trình xử lý

Các phương pháp xử lý vấn đề dữ liệu

Sau khi phát hiện các vấn đề thông qua bảng Frequencies, chúng ta có nhiều lựa chọn xử lý tùy thuộc vào tính chất và mức độ nghiêm trọng của vấn đề.

Xử lý giá trị ngoài phạm vi

Phương án 1: Sửa chữa dữ liệu

Áp dụng khi có thể xác định được giá trị đúng từ nguồn gốc:

  • Quay lại kiểm tra bảng hỏi gốc
  • Liên hệ lại với người cung cấp dữ liệu
  • Sử dụng logic nghiệp vụ để suy luận
  • Áp dụng các quy tắc chuyển đổi đã định trước

Phương án 2: Mã hóa thành missing

Khi không thể xác định được giá trị chính xác:

  • Chuyển giá trị không hợp lệ thành System Missing
  • Áp dụng các phương pháp xử lý missing phù hợp
  • Đảm bảo tỷ lệ missing không quá cao

Phương án 3: Loại bỏ quan sát

Chỉ áp dụng trong trường hợp đặc biệt:

  • Số lượng quan sát bị lỗi rất ít (nhỏ hơn 1%)
  • Có đủ quan sát hợp lệ cho phân tích
  • Không ảnh hưởng đến tính đại diện của mẫu
  • Đã cân nhắc tất cả các phương án khác

Xử lý missing values

Đối với vấn đề dữ liệu thiếu, có nhiều phương pháp xử lý tinh vi hơn:

Phương pháp Listwise Deletion

  • Loại bỏ toàn bộ quan sát có bất kỳ giá trị missing nào
  • Đơn giản nhưng có thể mất nhiều dữ liệu
  • Phù hợp khi tỷ lệ missing thấp và ngẫu nhiên

Phương pháp Imputation

  • Thay thế missing bằng giá trị ước lượng
  • Có thể sử dụng mean, median, mode
  • Hoặc các phương pháp phức tạp hơn như Multiple Imputation

Lưu ý quan trọng và cảnh báo

Khi thực hiện kiểm tra dữ liệu nhập trong thực hành kinh tế lượng, cần chú ý những điểm quan trọng sau:

Về quy trình thực hiện

Nguyên tắc quan trọng: Luôn sao lưu dữ liệu gốc trước khi thực hiện bất kỳ thay đổi nào. Mọi thao tác sửa đổi dữ liệu cần được ghi chép đầy đủ để có thể kiểm tra và reproduce sau này.

Về tài liệu hóa

  • Ghi chép chi tiết: Tất cả các vấn đề phát hiện và cách xử lý
  • Lưu trữ version: Giữ lại các phiên bản khác nhau của dữ liệu
  • Báo cáo minh bạch: Nêu rõ trong báo cáo các vấn đề và cách xử lý
  • Validation: Kiểm tra lại kết quả sau mỗi bước xử lý

Về tiêu chuẩn chất lượng

Các tiêu chuẩn tối thiểu cần đạt được:

  • Missing rate < 5%: Cho các biến quan trọng
  • No out-of-range values: Tất cả giá trị trong phạm vi hợp lệ
  • Logical consistency: Các biến liên quan phải nhất quán
  • Sufficient sample size: Đủ quan sát cho từng nhóm phân tích

Các lỗi thường gặp

Lỗi phổ biến khi kiểm tra dữ liệu:

  • Chỉ kiểm tra một số biến quan trọng, bỏ qua các biến khác
  • Không ghi chép lại quá trình xử lý
  • Sửa đổi dữ liệu mà không sao lưu bản gốc
  • Không kiểm tra lại sau khi xử lý
  • Không báo cáo minh bạch về các vấn đề đã phát hiện

Kết nối với các bước tiếp theo

Kiểm tra dữ liệu nhập bằng bảng Frequencies chỉ là bước đầu tiên trong quy trình chuẩn bị dữ liệu toàn diện. Sau bước này, chúng ta cần tiếp tục với:

Các bước tiếp theo trong quy trình

  • Kiểm tra missing values: Phân tích mẫu hình và xử lý dữ liệu thiếu
  • Phát hiện outliers: Xác định và xử lý các điểm dị biệt
  • Kiểm tra assumptions: Đánh giá các giả định của phương pháp phân tích
  • Data transformation: Biến đổi dữ liệu nếu cần thiết
  • Final validation: Kiểm tra cuối cùng trước phân tích chính

Tích hợp với quy trình nghiên cứu

Việc kiểm tra dữ liệu cần được tích hợp chặt chẽ với:

  • Research design: Thiết kế nghiên cứu và thu thập dữ liệu
  • Statistical analysis plan: Kế hoạch phân tích thống kê
  • Quality assurance: Hệ thống đảm bảo chất lượng
  • Reporting standards: Tiêu chuẩn báo cáo kết quả

Tổng kết

Kiểm tra dữ liệu nhập bằng bảng tần suất Frequencies là bước đầu tiên nhưng cực kỳ quan trọng trong thực hành kinh tế lượng. Thông qua việc sử dụng công cụ này trong SPSS, chúng ta có thể nhanh chóng phát hiện và đánh giá các vấn đề cơ bản về chất lượng dữ liệu.

Quy trình kiểm tra dữ liệu không chỉ giúp đảm bảo tính chính xác của các phân tích tiếp theo, mà còn thể hiện tính chuyên nghiệp và tuân thủ các tiêu chuẩn quốc tế trong nghiên cứu kinh tế lượng. Việc đầu tư thời gian và công sức vào bước này sẽ mang lại lợi ích to lớn cho toàn bộ quá trình nghiên cứu.

Quan trọng nhất, việc kiểm tra dữ liệu cần được thực hiện một cách có hệ thống, được ghi chép đầy đủ, và luôn tuân thủ nguyên tắc minh bạch trong nghiên cứu khoa học. Chỉ khi có nền tảng dữ liệu chất lượng cao, chúng ta mới có thể đưa ra những kết luận đáng tin cậy và có ý nghĩa thực tiễn trong lĩnh vực kinh tế.

Điểm chính cần nhớ:

  • Frequencies là công cụ đầu tiên và quan trọng nhất trong Data Screening
  • Luôn kiểm tra cả bảng Statistics (missing info) và bảng từng biến (value ranges)
  • Ghi chép đầy đủ mọi vấn đề phát hiện và cách xử lý
  • Không sửa đổi dữ liệu gốc mà không sao lưu
  • Data Screening là quy trình liên tục, không chỉ một lần kiểm tra
  • Chất lượng dữ liệu quyết định độ tin cậy của toàn bộ nghiên cứu

Phụ lục: Code trong các phần mềm khác

Để hỗ trợ các bạn làm quen với nhiều công cụ phân tích khác nhau trong thực hành kinh tế lượng, phần này cung cấp code tương đương cho việc kiểm tra dữ liệu nhập trong SPSS Syntax, Stata, R và Python.

SPSS Syntax

SPSS Syntax (.sps)


* Kiểm tra dữ liệu nhập bằng bảng tần suất trong SPSS
* Mở file dữ liệu
GET FILE='/data/loc-quan-sat.sav'.

* Hiển thị thông tin cơ bản về dataset
DISPLAY DICTIONARY.

* Tạo bảng tần suất cho tất cả các biến
FREQUENCIES VARIABLES=ALL
  /ORDER=ANALYSIS
  /STATISTICS=DEFAULT
  /BARCHART FREQ
  /HISTOGRAM
  /FORMAT=NOTABLE.

* Kiểm tra từng biến cụ thể (ví dụ với biến income)
FREQUENCIES VARIABLES=income
  /ORDER=VALUE
  /STATISTICS=DEFAULT MEAN MEDIAN MODE STDDEV VARIANCE
  /BARCHART FREQ
  /HISTOGRAM NORMAL.

* Kiểm tra missing values chi tiết
FREQUENCIES VARIABLES=ALL
  /FORMAT=NOTABLE
  /MISSING=INCLUDE
  /STATISTICS=DEFAULT.

* Tạo bảng crosstab để kiểm tra logic consistency
CROSSTABS
  /TABLES=income BY education
  /FORMAT=AVALUE TABLES
  /STATISTICS=CHISQ 
  /CELLS=COUNT ROW COLUMN TOTAL 
  /COUNT ROUND CELL.

* Sử dụng EXAMINE để phát hiện outliers
EXAMINE VARIABLES=income education age
  /PLOT BOXPLOT STEMLEAF HISTOGRAM NPPLOT
  /COMPARE GROUPS
  /STATISTICS DESCRIPTIVES EXTREME
  /CINTERVAL 95
  /MISSING LISTWISE
  /NOTOTAL.

* Tạo syntax để tìm kiếm giá trị cụ thể
* Ví dụ: tìm các quan sát có income = 6
SELECT IF (income = 6).
LIST CASES FROM 1 TO 10.
EXECUTE.

* Reset selection
SELECT IF NOT SYSMIS(income).
EXECUTE.

* Kiểm tra data integrity
AGGREGATE
  /OUTFILE=* MODE=ADDVARIABLES
  /BREAK=
  /N_VALID=N.

* Tạo báo cáo tóm tắt data quality
FREQUENCIES VARIABLES=ALL
  /FORMAT=NOTABLE
  /STATISTICS=MEAN MEDIAN MODE STDDEV MINIMUM MAXIMUM
  /ORDER=ANALYSIS.

* Export kết quả sang Excel để review
OUTPUT EXPORT
  /CONTENTS EXPORT=VISIBLE LAYERS=PRINTSETTING MODELVIEWS=PRINTSETTING
  /XLS DOCUMENTFILE='/output/data_screening_results.xls'
  /OPERATION=CREATEFILE.

Stata

Stata (.do)


* Kiểm tra dữ liệu nhập trong Stata
* Mở dữ liệu
use "/data/loc-quan-sat.dta", clear

* Hiển thị thông tin tổng quan về dataset
describe
codebook

* Kiểm tra missing values cho tất cả biến
misstable summarize

* Tạo bảng tần suất cho tất cả biến
foreach var of varlist _all {
    display "=== Frequency table for `var' ==="
    tabulate `var', missing
    display ""
}

* Kiểm tra biến income cụ thể
tabulate income, missing
summarize income, detail

* Kiểm tra giá trị ngoài phạm vi (ví dụ income > 5)
count if income > 5 & !missing(income)
list if income > 5 & !missing(income)

* Tạo indicator cho missing values
foreach var of varlist _all {
    generate miss_`var' = missing(`var')
    label variable miss_`var' "Missing indicator for `var'"
}

* Phân tích pattern missing
misstable patterns

* Kiểm tra data integrity
* Ví dụ: income phải từ 1-5
assert income >= 1 & income <= 5 if !missing(income) * Tạo biến flag cho các quan sát có vấn đề generate flag_problem = 0 replace flag_problem = 1 if income > 5 & !missing(income)
replace flag_problem = 1 if income < 1 & !missing(income)

* Liệt kê các quan sát có vấn đề
list if flag_problem == 1

* Kiểm tra consistency giữa các biến
tabulate income education, missing

* Tạo summary statistics
summarize, detail

* Tạo histogram để kiểm tra phân phối
foreach var of varlist income education age {
    histogram `var', discrete percent ///
        title("Distribution of `var'") ///
        xtitle("`var'") ytitle("Percent")
    graph export "`var'_histogram.png", replace
}

* Kiểm tra outliers bằng box plot
foreach var of varlist income education age {
    graph box `var', title("Box plot of `var'")
    graph export "`var'_boxplot.png", replace
}

* Tạo báo cáo data quality
estpost summarize _all
esttab using "data_quality_report.rtf", ///
    cells("count mean sd min max") ///
    title("Data Quality Report") replace

* Export dữ liệu đã clean để sử dụng
keep if flag_problem == 0
save "/data/cleaned_data.dta", replace

* Ghi log về các vấn đề đã phát hiện
file open logfile using "data_issues.txt", write replace
file write logfile "Data Quality Issues Found:" _n
file write logfile "=========================" _n
quietly count if flag_problem == 1
file write logfile "Number of problematic observations: " r(N) _n
file close logfile

R

R (.R)


# Kiểm tra dữ liệu nhập trong R
# Cài đặt và tải các package cần thiết
if (!require(foreign)) install.packages("foreign")
if (!require(dplyr)) install.packages("dplyr")
if (!require(VIM)) install.packages("VIM")
if (!require(Hmisc)) install.packages("Hmisc")
if (!require(psych)) install.packages("psych")
if (!require(ggplot2)) install.packages("ggplot2")
if (!require(gridExtra)) install.packages("gridExtra")

library(foreign)
library(dplyr)
library(VIM)
library(Hmisc)
library(psych)
library(ggplot2)
library(gridExtra)

# Đọc dữ liệu SPSS
data <- read.spss("/data/loc-quan-sat.sav", to.data.frame = TRUE)

# Hiển thị thông tin cơ bản về dataset
cat("THÔNG TIN CƠ BẢN VỀ DATASET\n")
cat("============================\n")
str(data)
cat("\nKích thước dữ liệu:", dim(data), "\n")
cat("Tên các biến:", names(data), "\n")

# Kiểm tra missing values
cat("\nPHÂN TÍCH MISSING VALUES\n")
cat("========================\n")
missing_summary <- data %>%
  summarise_all(~sum(is.na(.))) %>%
  gather(key = "Variable", value = "Missing_Count") %>%
  mutate(Missing_Percent = round(Missing_Count / nrow(data) * 100, 2)) %>%
  arrange(desc(Missing_Count))

print(missing_summary)

# Visualize missing pattern
VIM::aggr(data, col=c('navyblue','red'), 
          numbers=TRUE, sortVars=TRUE, 
          labels=names(data), cex.axis=.7, 
          gap=3, ylab=c("Histogram of missing data","Pattern"))

# Tạo bảng tần suất cho từng biến
cat("\nBẢNG TẦN SUẤT CHO TỪNG BIẾN\n")
cat("============================\n")

create_frequency_table <- function(var, var_name) {
  cat("\n--- Biến:", var_name, "---\n")
  
  # Basic frequency table
  freq_table <- table(var, useNA = "always")
  prop_table <- prop.table(freq_table) * 100
  
  result <- data.frame(
    Value = names(freq_table),
    Frequency = as.numeric(freq_table),
    Percent = round(as.numeric(prop_table), 2)
  )
  
  print(result)
  
  # Check for out-of-range values
  if (var_name == "income") {
    out_of_range <- sum(var > 5 | var < 1, na.rm = TRUE) if (out_of_range > 0) {
      cat("⚠️  CẢNH BÁO: Phát hiện", out_of_range, "giá trị ngoài phạm vi (1-5)\n")
      invalid_values <- var[var > 5 | var < 1]
      cat("Các giá trị không hợp lệ:", unique(invalid_values[!is.na(invalid_values)]), "\n")
    }
  }
  
  return(result)
}

# Áp dụng cho tất cả các biến
freq_results <- list()
for (i in 1:ncol(data)) {
  if (is.numeric(data[[i]]) || is.factor(data[[i]])) {
    freq_results[[names(data)[i]]] <- create_frequency_table(data[[i]], names(data)[i])
  }
}

# Phân tích chi tiết biến income
cat("\nPHÂN TÍCH CHI TIẾT BIẾN INCOME\n")
cat("==============================\n")
if ("income" %in% names(data)) {
  income_stats <- describe(data$income)
  print(income_stats)
  
  # Tìm các quan sát có giá trị income = 6
  problematic_obs <- which(data$income == 6) if (length(problematic_obs) > 0) {
    cat("\nCác quan sát có income = 6 (không hợp lệ):\n")
    cat("Vị trí (row numbers):", problematic_obs, "\n")
    
    # Hiển thị chi tiết các quan sát này
    problem_data <- data[problematic_obs, ]
    print(problem_data)
  }
}

# Tạo visualizations
cat("\nTẠO BIỂU ĐỒ KIỂM TRA DỮ LIỆU\n")
cat("==============================\n")

# Function để tạo histogram
create_histogram <- function(var, var_name) {
  if (is.numeric(var)) {
    ggplot(data.frame(x = var), aes(x = x)) +
      geom_histogram(bins = 20, fill = "lightblue", color = "black", alpha = 0.7) +
      labs(title = paste("Histogram của", var_name),
           x = var_name, y = "Tần số") +
      theme_minimal()
  } else {
    ggplot(data.frame(x = var), aes(x = x)) +
      geom_bar(fill = "lightblue", color = "black", alpha = 0.7) +
      labs(title = paste("Bar chart của", var_name),
           x = var_name, y = "Tần số") +
      theme_minimal() +
      theme(axis.text.x = element_text(angle = 45, hjust = 1))
  }
}

# Tạo plots cho các biến quan trọng
plots <- list()
important_vars <- c("income", "education", "age")
for (var in important_vars) {
  if (var %in% names(data)) {
    plots[[var]] <- create_histogram(data[[var]], var) } } # Hiển thị plots if (length(plots) > 0) {
  do.call(grid.arrange, c(plots, ncol = 2))
}

# Data quality assessment
cat("\nBÁO CÁO CHẤT LƯỢNG DỮ LIỆU\n")
cat("===========================\n")

quality_report <- data.frame(
  Variable = names(data),
  Data_Type = sapply(data, class),
  Missing_Count = sapply(data, function(x) sum(is.na(x))),
  Missing_Percent = round(sapply(data, function(x) sum(is.na(x))/length(x)*100), 2),
  Unique_Values = sapply(data, function(x) length(unique(x[!is.na(x)]))),
  Min_Value = sapply(data, function(x) if(is.numeric(x)) min(x, na.rm=TRUE) else NA),
  Max_Value = sapply(data, function(x) if(is.numeric(x)) max(x, na.rm=TRUE) else NA)
)

print(quality_report)

# Identify problematic variables
cat("\nCHỈ SỐ CHẤT LƯỢNG DỮ LIỆU\n")
cat("==========================\n")

high_missing <- quality_report$Variable[quality_report$Missing_Percent > 5]
if (length(high_missing) > 0) {
  cat("⚠️  Biến có tỷ lệ missing cao (>5%):", paste(high_missing, collapse = ", "), "\n")
}

# Check for potential outliers using IQR method
cat("\nKIỂM TRA OUTLIERS TIỀM NĂNG\n")
cat("============================\n")

check_outliers <- function(var, var_name) {
  if (is.numeric(var)) {
    Q1 <- quantile(var, 0.25, na.rm = TRUE)
    Q3 <- quantile(var, 0.75, na.rm = TRUE)
    IQR <- Q3 - Q1
    lower_bound <- Q1 - 1.5 * IQR
    upper_bound <- Q3 + 1.5 * IQR
    
    outliers <- var[var < lower_bound | var > upper_bound]
    outliers <- outliers[!is.na(outliers)] if (length(outliers) > 0) {
      cat("Biến", var_name, "có", length(outliers), "outliers tiềm năng\n")
      cat("Giá trị outliers:", unique(outliers), "\n")
    }
  }
}

for (i in 1:ncol(data)) {
  if (is.numeric(data[[i]])) {
    check_outliers(data[[i]], names(data)[i])
  }
}

# Export results
cat("\nXUẤT KẾT QUẢ\n")
cat("============\n")

# Save quality report
write.csv(quality_report, "data_quality_report.csv", row.names = FALSE)
write.csv(missing_summary, "missing_values_summary.csv", row.names = FALSE)

# Create a comprehensive report
sink("data_screening_report.txt")
cat("BÁO CÁO KIỂM TRA DỮ LIỆU NHẬP\n")
cat("==============================\n")
cat("Ngày tạo:", Sys.Date(), "\n")
cat("Số quan sát:", nrow(data), "\n")
cat("Số biến:", ncol(data), "\n\n")

cat("TÓM TẮT MISSING VALUES:\n")
print(missing_summary)

cat("\nTÓM TẮT CHẤT LƯỢNG DỮ LIỆU:\n")
print(quality_report)

if (length(high_missing) > 0) {
  cat("\nCẢNH BÁO:\n")
  cat("- Các biến có tỷ lệ missing cao:", paste(high_missing, collapse = ", "), "\n")
}

cat("\nKẾT LUẬN:\n")
cat("- Cần xem xét xử lý missing values cho các biến có tỷ lệ missing cao\n")
cat("- Kiểm tra và xử lý các giá trị ngoài phạm vi\n")
cat("- Xem xét loại bỏ hoặc xử lý outliers nếu cần thiết\n")
sink()

cat("Đã xuất báo cáo chi tiết vào file 'data_screening_report.txt'\n")

Python

Python (.py)


# Kiểm tra dữ liệu nhập trong Python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import pyreadstat
import warnings
warnings.filterwarnings('ignore')

# Thiết lập matplotlib cho tiếng Việt
plt.rcParams['font.family'] = 'DejaVu Sans'
plt.rcParams['figure.figsize'] = (12, 8)

print("KIỂM TRA DỮ LIỆU NHẬP - DATA SCREENING")
print("="*50)

# Đọc dữ liệu SPSS
try:
    data, meta = pyreadstat.read_sav('/data/loc-quan-sat.sav')
    print("✅ Đọc dữ liệu thành công")
except Exception as e:
    print(f"❌ Lỗi đọc dữ liệu: {e}")
    # Tạo dữ liệu mẫu cho demo
    np.random.seed(123)
    data = pd.DataFrame({
        'income': np.random.choice([1, 2, 3, 4, 5, 6], size=100, p=[0.2, 0.2, 0.2, 0.2, 0.15, 0.05]),
        'education': np.random.choice([1, 2, 3, 4], size=100),
        'age': np.random.normal(35, 10, 100).astype(int)
    })
    # Thêm một số missing values
    data.loc[np.random.choice(data.index, 5), 'income'] = np.nan

# Hiển thị thông tin cơ bản
print(f"\nTHÔNG TIN CƠ BẢN VỀ DATASET")
print("-" * 30)
print(f"Kích thước dữ liệu: {data.shape}")
print(f"Số quan sát: {data.shape[0]}")
print(f"Số biến: {data.shape[1]}")
print(f"Tên các biến: {list(data.columns)}")

# Hiển thị info chi tiết
print(f"\nCẤU TRÚC DỮ LIỆU:")
print(data.info())

# Kiểm tra missing values
print(f"\nPHÂN TÍCH MISSING VALUES")
print("=" * 30)

missing_summary = pd.DataFrame({
    'Biến': data.columns,
    'Missing_Count': data.isnull().sum(),
    'Missing_Percent': round(data.isnull().sum() / len(data) * 100, 2),
    'Data_Type': data.dtypes
})
missing_summary = missing_summary.sort_values('Missing_Count', ascending=False)
print(missing_summary)

# Visualize missing values
if missing_summary['Missing_Count'].sum() > 0:
    plt.figure(figsize=(10, 6))
    missing_data = data.isnull().sum()
    missing_data = missing_data[missing_data > 0]
    
    plt.subplot(1, 2, 1)
    missing_data.plot(kind='bar', color='salmon')
    plt.title('Số lượng Missing Values')
    plt.ylabel('Số quan sát')
    plt.xticks(rotation=45)
    
    plt.subplot(1, 2, 2)
    (missing_data / len(data) * 100).plot(kind='bar', color='lightcoral')
    plt.title('Tỷ lệ Missing Values (%)')
    plt.ylabel('Phần trăm')
    plt.xticks(rotation=45)
    
    plt.tight_layout()
    plt.show()

# Tạo bảng tần suất cho từng biến
print(f"\nBẢNG TẦN SUẤT CHO TỪNG BIẾN")
print("=" * 30)

def create_frequency_table(series, var_name):
    print(f"\n--- Biến: {var_name} ---")
    
    # Tạo bảng tần suất
    freq_table = series.value_counts(dropna=False).sort_index()
    percent_table = series.value_counts(normalize=True, dropna=False).sort_index() * 100
    
    result = pd.DataFrame({
        'Giá_trị': freq_table.index,
        'Tần_suất': freq_table.values,
        'Phần_trăm': round(percent_table.values, 2)
    })
    
    print(result)
    
    # Kiểm tra giá trị ngoài phạm vi cho biến income
    if var_name == 'income':
        out_of_range = series[(series > 5) | (series < 1)].dropna() if len(out_of_range) > 0:
            print(f"⚠️  CẢNH BÁO: Phát hiện {len(out_of_range)} giá trị ngoài phạm vi (1-5)")
            print(f"Các giá trị không hợp lệ: {list(out_of_range.unique())}")
            
            # Tìm vị trí các quan sát có vấn đề
            problematic_indices = series[(series > 5) | (series < 1)].index.tolist() print(f"Vị trí các quan sát có vấn đề: {problematic_indices}") return result # Áp dụng cho tất cả các biến frequency_results = {} for col in data.columns: if data[col].dtype in ['int64', 'float64', 'object', 'category']: frequency_results[col] = create_frequency_table(data[col], col) # Phân tích chi tiết biến income if 'income' in data.columns: print(f"\nPHÂN TÍCH CHI TIẾT BIẾN INCOME") print("=" * 30) income_stats = data['income'].describe() print(income_stats) # Tìm các quan sát có income = 6 problematic_obs = data[data['income'] == 6].index.tolist() if len(problematic_obs) > 0:
        print(f"\nCác quan sát có income = 6 (không hợp lệ):")
        print(f"Số lượng: {len(problematic_obs)}")
        print(f"Vị trí (index): {problematic_obs}")
        
        # Hiển thị chi tiết
        problem_data = data.loc[problematic_obs]
        print("\nDữ liệu chi tiết các quan sát có vấn đề:")
        print(problem_data)

# Tạo visualizations
print(f"\nTẠO BIỂU ĐỒ KIỂM TRA DỮ LIỆU")
print("=" * 30)

def create_distribution_plot(series, var_name):
    """Tạo biểu đồ phân phối cho biến"""
    fig, axes = plt.subplots(1, 2, figsize=(15, 5))
    
    # Histogram
    if series.dtype in ['int64', 'float64']:
        series.hist(bins=20, ax=axes[0], color='lightblue', edgecolor='black', alpha=0.7)
        axes[0].set_title(f'Histogram của {var_name}')
        axes[0].set_xlabel(var_name)
        axes[0].set_ylabel('Tần số')
        
        # Box plot
        series.plot(kind='box', ax=axes[1], color='lightgreen')
        axes[1].set_title(f'Box plot của {var_name}')
        axes[1].set_ylabel(var_name)
    else:
        # Bar chart cho categorical variables
        value_counts = series.value_counts()
        value_counts.plot(kind='bar', ax=axes[0], color='lightblue', edgecolor='black')
        axes[0].set_title(f'Bar chart của {var_name}')
        axes[0].set_xlabel(var_name)
        axes[0].set_ylabel('Tần số')
        axes[0].tick_params(axis='x', rotation=45)
        
        # Pie chart
        value_counts.plot(kind='pie', ax=axes[1], autopct='%1.1f%%')
        axes[1].set_title(f'Pie chart của {var_name}')
        axes[1].set_ylabel('')
    
    plt.tight_layout()
    plt.show()

# Tạo plots cho các biến quan trọng
important_vars = ['income', 'education', 'age']
for var in important_vars:
    if var in data.columns:
        create_distribution_plot(data[var], var)

# Data quality assessment
print(f"\nBÁO CÁO CHẤT LƯỢNG DỮ LIỆU")
print("=" * 30)

quality_report = pd.DataFrame({
    'Biến': data.columns,
    'Kiểu_dữ_liệu': data.dtypes,
    'Số_missing': data.isnull().sum(),
    'Tỷ_lệ_missing': round(data.isnull().sum() / len(data) * 100, 2),
    'Số_giá_trị_unique': data.nunique(),
    'Giá_trị_min': data.min(),
    'Giá_trị_max': data.max()
})

print(quality_report)

# Xác định các biến có vấn đề
print(f"\nCHỈ SỐ CHẤT LƯỢNG DỮ LIỆU")
print("=" * 30)

high_missing_vars = quality_report[quality_report['Tỷ_lệ_missing'] > 5]['Biến'].tolist()
if high_missing_vars:
    print(f"⚠️  Biến có tỷ lệ missing cao (>5%): {', '.join(high_missing_vars)}")

# Kiểm tra outliers
print(f"\nKIỂM TRA OUTLIERS TIỀM NĂNG")
print("=" * 30)

def detect_outliers_iqr(series, var_name):
    """Phát hiện outliers sử dụng phương pháp IQR"""
    if series.dtype in ['int64', 'float64']:
        Q1 = series.quantile(0.25)
        Q3 = series.quantile(0.75)
        IQR = Q3 - Q1
        lower_bound = Q1 - 1.5 * IQR
        upper_bound = Q3 + 1.5 * IQR
        
        outliers = series[(series < lower_bound) | (series > upper_bound)]
        
        if len(outliers) > 0:
            print(f"Biến {var_name} có {len(outliers)} outliers tiềm năng")
            print(f"Phạm vi hợp lệ: [{lower_bound:.2f}, {upper_bound:.2f}]")
            print(f"Giá trị outliers: {sorted(outliers.unique())}")
            return outliers.index.tolist()
    return []

outlier_indices = {}
for col in data.columns:
    if data[col].dtype in ['int64', 'float64']:
        outliers = detect_outliers_iqr(data[col], col)
        if outliers:
            outlier_indices[col] = outliers

# Tạo ma trận correlation để kiểm tra logic consistency
if len(data.select_dtypes(include=[np.number]).columns) > 1:
    print(f"\nMA TRẬN TƯƠNG QUAN")
    print("=" * 20)
    
    correlation_matrix = data.select_dtypes(include=[np.number]).corr()
    print(correlation_matrix)
    
    # Heatmap
    plt.figure(figsize=(10, 8))
    sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0,
                square=True, linewidths=0.5)
    plt.title('Ma trận tương quan giữa các biến số')
    plt.tight_layout()
    plt.show()

# Tạo báo cáo tổng hợp
print(f"\nTẠO BÁO CÁO TỔNG HỢP")
print("=" * 25)

# Export results
quality_report.to_csv('data_quality_report.csv', index=False)
missing_summary.to_csv('missing_values_summary.csv', index=False)

# Tạo báo cáo text chi tiết
with open('data_screening_report.txt', 'w', encoding='utf-8') as f:
    f.write("BÁO CÁO KIỂM TRA DỮ LIỆU NHẬP\n")
    f.write("=" * 35 + "\n")
    f.write(f"Ngày tạo: {pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
    f.write(f"Số quan sát: {data.shape[0]}\n")
    f.write(f"Số biến: {data.shape[1]}\n\n")
    
    f.write("TÓM TẮT MISSING VALUES:\n")
    f.write(missing_summary.to_string(index=False))
    f.write("\n\n")
    
    f.write("TÓM TẮT CHẤT LƯỢNG DỮ LIỆU:\n")
    f.write(quality_report.to_string(index=False))
    f.write("\n\n")
    
    if high_missing_vars:
        f.write("CẢNH BÁO:\n")
        f.write(f"- Các biến có tỷ lệ missing cao: {', '.join(high_missing_vars)}\n")
    
    f.write("\nKẾT LUẬN VÀ KHUYẾN NGHỊ:\n")
    f.write("- Cần xem xét xử lý missing values cho các biến có tỷ lệ missing cao\n")
    f.write("- Kiểm tra và xử lý các giá trị ngoài phạm vi\n")
    f.write("- Xem xét loại bỏ hoặc xử lý outliers nếu cần thiết\n")
    f.write("- Đảm bảo logic consistency giữa các biến liên quan\n")

print("✅ Đã xuất các file báo cáo:")
print("   - data_quality_report.csv")
print("   - missing_values_summary.csv") 
print("   - data_screening_report.txt")

# Tạo summary dashboard
fig, axes = plt.subplots(2, 2, figsize=(15, 12))

# Missing values summary
missing_counts = data.isnull().sum()
missing_counts = missing_counts[missing_counts > 0]
if len(missing_counts) > 0:
    axes[0, 0].bar(range(len(missing_counts)), missing_counts.values, color='salmon')
    axes[0, 0].set_title('Missing Values by Variable')
    axes[0, 0].set_xticks(range(len(missing_counts)))
    axes[0, 0].set_xticklabels(missing_counts.index, rotation=45)
    axes[0, 0].set_ylabel('Count')
else:
    axes[0, 0].text(0.5, 0.5, 'No Missing Values', ha='center', va='center')
    axes[0, 0].set_title('Missing Values Summary')

# Data types distribution
dtype_counts = data.dtypes.value_counts()
axes[0, 1].pie(dtype_counts.values, labels=dtype_counts.index, autopct='%1.1f%%')
axes[0, 1].set_title('Distribution of Data Types')

# Variable count
axes[1, 0].bar(['Total Variables', 'Numeric Variables', 'Non-Numeric Variables'],
               [len(data.columns), 
                len(data.select_dtypes(include=[np.number]).columns),
                len(data.select_dtypes(exclude=[np.number]).columns)],
               color=['lightblue', 'lightgreen', 'lightyellow'])
axes[1, 0].set_title('Variable Type Summary')
axes[1, 0].set_ylabel('Count')

# Sample size and completeness
completeness = (1 - data.isnull().sum() / len(data)) * 100
axes[1, 1].hist(completeness, bins=10, color='lightcoral', edgecolor='black', alpha=0.7)
axes[1, 1].set_title('Data Completeness Distribution')
axes[1, 1].set_xlabel('Completeness (%)')
axes[1, 1].set_ylabel('Frequency')

plt.tight_layout()
plt.savefig('data_screening_dashboard.png', dpi=300, bbox_inches='tight')
plt.show()

print(f"\n{'='*50}")
print("KIỂM TRA DỮ LIỆU NHẬP HOÀN TẤT")
print(f"{'='*50}")

Tài liệu tham khảo

Để nắm vững hơn về kiểm tra dữ liệu nhập trong thực hành kinh tế lượng, các bạn có thể tham khảo:

  • IBM SPSS Statistics Documentation – Descriptive Statistics and Frequencies Procedures
  • Field, A. (2018). Discovering Statistics Using IBM SPSS Statistics (5th ed.). Sage Publications – Chapter 5: Data Screening
  • Tabachnick, B. G., & Fidell, L. S. (2019). Using Multivariate Statistics (7th ed.). Pearson – Chapter 4: Cleaning Up Your Act
  • Hair, J. F., Black, W. C., Babin, B. J., & Anderson, R. E. (2019). Multivariate Data Analysis (8th ed.). Cengage Learning – Chapter 2: Examining Your Data
  • Osborne, J. W. (2013). Best Practices in Data Cleaning. Sage Publications
  • Van den Broeck, J., Cunningham, S. A., Eeckels, R., & Herbst, K. (2005). Data cleaning: detecting, diagnosing, and editing data abnormalities. PLoS Medicine, 2(10), e267

Tài liệu tham khảo

  • Rahm, E., & Do, H. H. (2000). Data cleaning: Problems and current approaches. IEEE Data Engineering Bulletin, 23(4), 3-13
  • Kim, W., Choi, B. J., Hong, E. K., Kim, S. K., & Lee, D. (2003). A taxonomy of dirty data. Data Mining and Knowledge Discovery, 7(1), 81-99
  • Maletic, J. I., & Marcus, A. (2000). Data cleansing: Beyond integrity analysis. Conference on Information Quality, 200-209
  • Müller, H., & Freytag, J. C. (2003). Problems, methods, and challenges in comprehensive data cleansing. Technical Report HUB-IB-164, Humboldt University Berlin

Xem thêm các bài viết liên quan

Các chủ đề tiếp theo trong quy trình Data Screening:

Xem thêm
Back to top button