Trong thực hành phân tích dữ liệu chúng ta thường gặp những biến số có giá trị là text (chữ viết). Khi nhập dữ liệu, nhiều lỗi xảy ra gây ra những khó khăn cho người phân tích vì phải làm sạch lỗi dữ liệu (dọn rác) trước khi đưa dữ liệu vào phân tích.
Ví dụ, khi nhập thông tin về địa chỉ của khách hàng với địa danh là “Thanh Sơn”, thì những giá trị nhập vào có thể là “Thanh Sơn”, “Thanh sơn”, “thanh sơ”, “thanh Sơn”, “THANH SƠN”, “Than sơn”, “Tthanh so”…v.v. Những lỗi nhập dữ liệu này làm cho các phần mềm phân tích nhận diện những giá trị trên đây là những địa danh khác nhau, dẫn đến mô tả, tóm tắt dữ liệu theo nhóm bị sai.
Vì thế trước khi phân tích, chúng ta phải chỉnh sửa tất cả những sai sót trên, để trở thành một địa danh duy nhất là “Thanh Sơn”.
Nếu chỉ một vài chỗ sai sót, chúng ta cỏ thể xóa row bị lỗi. Tuy nhiên, khi số row bị lỗi nhiều, ví dụ có 100 khách hàng bị gõ nhầm địa chỉ là “Tthanh so” thì chúng ta không thể loại bỏ những dòng dữ liệu này mà phải chỉnh sửa thành một tên thống nhất, chẳng hạn là “Thanh Sơn”.
Kí tự viết HOA (upper case) hoặc có dấu như Tiếng Việt càng dễ tạo ra những sai sót.
Trong bài thực hành này, tôi muốn trình bày những thủ thuật sau:
Dữ liệu tôi sử dụng trong bài được thu thập từ một phòng khám để minh họa cho những lỗi nhập liệu có trong thực tế.
library(tidyverse)
## -- Attaching packages ----------------------------------------------------------------------------- tidyverse 1.2.1 --
## v ggplot2 2.2.1 v purrr 0.2.4
## v tibble 1.4.1 v dplyr 0.7.4
## v tidyr 0.7.2 v stringr 1.2.0
## v readr 1.1.1 v forcats 0.3.0
## Warning: package 'forcats' was built under R version 3.4.4
## -- Conflicts -------------------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library("readxl")
mydf <- read_excel("F:/R/Data/Clinic2019.xlsx")
mydf <- mydf[,-c(8,9)]
dim(mydf)
## [1] 229198 7
str(mydf)
## Classes 'tbl_df', 'tbl' and 'data.frame': 229198 obs. of 7 variables:
## $ ID : chr "0040466" "0060246" "0060540" "0060540" ...
## $ Date : POSIXct, format: "2010-04-17" "2010-06-08" ...
## $ name : chr "h<U+1EF7> mành long" "nguy<U+1EC5>n th<U+1ECB> kim phu<U+1EE3>ng" "chí nh<U+1EE5>c lìn" "chí nh<U+1EE5>c lìn" ...
## $ age : num 31 32 19 19 13 9 9 9 40 17 ...
## $ address : chr "ng<U+1ECD>c d<U+1ECB>nh" "gia canh" "phú di<U+1EC1>n" "phú di<U+1EC1>n" ...
## $ service : chr "general" "general" "gyneco" "obstetric" ...
## $ findings: chr "RLTH, tiêu ch<U+1EA3>y" "DD" "bt" "luu 7w" ...
head(mydf)
## # A tibble: 6 x 7
## ID Date name age addre~ servi~ findin~
## <chr> <dttm> <chr> <dbl> <chr> <chr> <chr>
## 1 0040466 2010-04-17 00:00:00 h<U+1EF7> mành ~ 31.0 ng<U+1ECD>c ~ gener~ RLTH, ~
## 2 0060246 2010-06-08 00:00:00 nguy<U+1EC5>n t~ 32.0 gia c~ gener~ DD
## 3 0060540 2010-07-10 00:00:00 chí nh<U+1EE5>c~ 19.0 phú d~ gyneco bt
## 4 0060540 2010-06-19 00:00:00 chí nh<U+1EE5>c~ 19.0 phú d~ obste~ luu 7w
## 5 "\u0089051095" 2018-03-01 00:00:00 hoàng ma~ 13.0 phú l~ gener~ dau b<U+1EE5>~
## 6 070714 2014-01-05 00:00:00 truong d~ 9.00 phú v~ gener~ dau b<U+1EE5>~
table(mydf$address)
##
## [hú l<U+1EE3>i [hú ng<U+1ECD>c [phú ng<U+1ECD>c [phú vinh <U+1EDF> tr<U+1ECD>
## 2 1 3 1 1
## <U+1EDF> xa 107 africa an giang AUS
## 1 1 1 47 1
## australia Australia b<U+1EA1>c li<U+1EC7>u b<U+1EA1>c liêu b<U+1EA3>o binh
## 5 1 1 14 1
## b<U+1EA3>o bình b<U+1EA3>o l<U+1ED9>c b<U+1EAF>c b<U+1EAF>c - la ngà b<U+1EAF>c bình
## 2 66 54 1 1
## b<U+1EAF>c c<U+1EA1>n b<U+1EAF>c giang b<U+1EBF>n tre b<U+1EED>u son bà r<U+1ECB>a
## 1 2 82 10 11
## bam cát tiên bàu hàm bên c<U+1EA1>nh BH biên h òa
## 1 3 2 11 1
## biên hòa biên Hòa bình d<U+1ECB>nh bình duong binh phu<U+1EDB>c
## 202 1 30 133 1
## bính phu<U+1EDB>c bình phu<U+1EDB>c bình thu<U+1EAD>n bình Thu<U+1EAD>n bò hàm
## 1 117 130 2 1
## bù d<U+1ED1>p bù dang buônmathu<U+1ED9>t c<U+1EA3>m m<U+1EF9> c<U+1EA7>n tho
## 1 6 1 2 24
## c<U+1EA7>u du<U+1EDD>ng c<U+1EA9>m m<U+1EF9> c<U+1EE7> chi cà mau cái mon
## 1 15 6 53 1
## cali cam ranh camphuchia campuchia cao lãnh
## 1 1 1 1 6
## cao nguyên cat tiên cát tiên cây gáo châu d<U+1ED1>c
## 1 2 53 4 12
## côn d<U+1EA3>o CVA d linh d<U+1EA1> t<U+1EBB> d<U+1EA1> t<U+1EC3>
## 1 3 1 5 1
## d<U+1EA1> t<U+1ED3>n d<U+1EA7>m doi d<U+1EA7>u giây d<U+1EAF>c l<U+1EAF>c d<U+1EAF>c l<U+1EAF>c
## 2 2 25 13 1
## d<U+1EAF>c lu d<U+1EAF>c lua d<U+1EAF>c lua. d<U+1EAF>c nông d<U+1EAF>c nông
## 1 11 1 48 1
## d<U+1ECB>nh quán d<U+1ECB>nh qán d<U+1ECB>nh qián d<U+1ECB>nh qquán d<U+1ECB>nh quan
## 9 1 3 1 10
## d<U+1ECB>nh quán d<U+1ECB>nh quán d<U+1ECB>nh Quán d<U+1ECB>nh quàn d<U+1ECB>nh quân
## 40435 8 379 2 1
## d<U+1ECB>nh qúan Ð<U+1ECB>nh quán Ð<U+1ECB>nh Quán d<U+1ECB>nh quná d<U+1ECB>nh uqán
## 7 8 22 1 4
## d<U+1ECB>nhn quán d<U+1ECB>nhquán d<U+1ED1>c mo d<U+1ED3>ng tháp d<U+1ED3>ng Tháp
## 1 4 2 43 7
## d<U+1ED3>ng xoài d<U+1EE9>c linh d<U+1EE9>c tr<U+1ECD>ng d0<U+1ECB>nh quán d0<U+1ECB>nh quán
## 23 35 11 2 2
## d9inh5 quán da hoai da hoai da kai dà l<U+1EA1>t
## 1 18 2 10 38
## Ðà L<U+1EA1>t da lat dà n<U+1EB5>ng dà nãng da t<U+1EBB>
## 2 1 7 1 3
## dac klao dahoai dahoai dài loan dak lak
## 1 3 2 13 4
## dak nông dak nông dak song daklak daklua
## 16 3 1 25 1
## daklua dakngo daknong daknông daknông
## 1 1 3 2 11
## dalat dambri dau lung di h5 quán di h5 quná
## 6 1 2 1 1
## di linh di<U+0323>nh qua´n di<U+1ECB>nh quán dinh quán dinh quán
## 77 1 2 21 8
## dinh quán dình quán dnh55 quán fd<U+1ECB>nh quán france
## 2 1 2 1 4
## France ga canh gai canh gài gòn gfia canh
## 1 2 2 1 3
## gi gi<U+1EA7>u dây gia canh gia acnh gia camj
## 1 1 2 3 5
## gia can gia canh gia Canh Gia canh Gia Canh
## 1 26049 121 3 2
## gia canh (B) gia canh 114 gia cnh gia ki<U+1EC7>m gia kiêm
## 3 2 1 85 2
## gia lai gia nghia gia tân gia Tân giang di<U+1EC1>n
## 8 1 3 1 7
## gic canh giia canh gio linh gò công gò v<U+1EA5>p
## 1 3 1 7 1
## GS h<U+1EA3>i duong h<U+1EA3>i phòng h<U+1EAD>u giang h<U+1ED1> nai
## 1 6 2 6 13
## h<U+1ED3>ng ng<U+1EF1> hà dông hà giang hà n<U+1ED9>i Ha Noi
## 1 1 4 21 1
## hà tinh hàm tân hàn qu<U+1ED1>c hanh son HCM
## 7 5 11 1 13
## hi<U+1EC7>p cu<U+1EDD>ng hi<U+1EC7>p Cu<U+1EDD>ng hi<U+1EC7>p d<U+1ED3>ng hi<U+1EC7>p l<U+1EE3>i hi<U+1EC7>p l<U+1EF1>c
## 1 10 6 4 48
## hi<U+1EC7>p nghia hi<U+1EC7>p nh<U+1EA5>t hi<U+1EC7>p quy<U+1EBF>t hi<U+1EC7>p tâm hi<U+1EC7>p tâm 1
## 5 3 1 21 26
## hi<U+1EC7>p tâm 2 hi<U+1EC7>p thu<U+1EAD>n hi<U+1EC7>p thuong HN hó nai
## 15 8 4 1 1
## hóc môn hongkong hu<U+1EBF> Hu<U+1EBF> khách xa
## 2 1 22 1 1
## khánh hòa kiên giang kim long ko bi<U+1EBF>t kom tum
## 4 24 2 1 1
## kon tum korea l<U+1ED9>c an l<U+1ED9>c ninh la bgà
## 1 11 1 4 1
## la gi la gnà la m6 d<U+1ED3>ng la ng<U+1EA3> la nga
## 1 2 2 4 1
## la ngà la Ngà La ngà là ngà la ngà /BT
## 17181 208 7 18 1
## la ngà 103 lam d<U+1ED3>ng lâm d<U+1ED3>ng langà lào cai
## 1 1 134 1 1
## ld ld<U+1ECB>nh quán long an long giao long khánh
## 1 1 48 1 145
## long thành long xuyên lonh khánh madagoui madagui
## 50 5 1 4 89
## malaysia Malaysia mepu mi<U+1EC1>n tây mi<U+1EC1>n Tây
## 1 4 1 28 1
## mi<U+1EC1>n trung Mi<U+1EC1>n Trung mui né na uy nam cát tiên
## 2 1 2 1 208
## nam cát Tiên nam cát tiuên nam d<U+1ECB>nh namcattien nauy
## 1 1 7 1 1
## NC Tiên NCTiên NG<U+1ECC>C Ð<U+1ECA>NH ng<U+1ECD>c d<U+1ECB>nh ng<U+1ECD>c 9inh5
## 1 1 1 5 2
## ng<U+1ECD>c d<U+1ECB>nh ng<U+1ECD>c d<U+1ECB>nh Ng<U+1ECD>c d<U+1ECB>nh ng<U+1ECD>c Ð<U+1ECB>nh ng<U+1ECD>c d<U+1ECB>nh quán
## 14051 21 5 144 4
## ng<U+1ECD>c di<U+1ECB>nh ng<U+1ECD>c dinh ng<U+1ECD>c dinh ng<U+1ECD>c dình ng<U+1ECD>c dinn
## 2 35 1 1 1
## ng<U+1ECD>c lâm ngc5 d<U+1ECB>nh ngh<U+1EC7> an ngh<U+1EC7> tinh ngo<U+0323>c di<U+0323>nh
## 12 1 49 2 1
## ngoài b<U+1EAF>c ngoc d<U+1ECB>nh ngôc d<U+1ECB>nh Nguy<U+1EC5>n Hu<U+1EC7> nha trang
## 2 13 3 1 8
## nhân co nhon tr<U+1EA1>ch Nhon Tr<U+1EA1>ch ninh bình ninh thu<U+1EAD>n
## 1 28 1 5 9
## norway NTN NTNhi<U+1EC7>m núi hu<U+1EE3>ng núi tu<U+1EE3>ng
## 1 60 25 2 152
## ohú l<U+1EE3>i ohú ng<U+1ECD>c p l<U+1EE3>i/Th Ði<U+1EC3>n p[hú l<U+1EE3>i pgú tân
## 1 1 1 1 1
## ph lâm ph1 ng<U+1ECD>c ph1u l<U+1EE3>i ph1u ng<U+1ECD>c ph1u tân
## 1 2 1 1 3
## phan rang phan thi<U+1EBF>t phan thiêt pháp phipl
## 3 10 1 3 3
## phú phú hòa phú l<U+1EE3>i phú ng<U+1ECD>c phú son
## 6 1 8 13 1
## phú tân phú vinh phú <U+1EE3>i phú 9i<U+1EC1>n phú an
## 1 3 1 1 23
## phú atn6 phú b<U+1EE5>ng phú bình phú cinh phú cu<U+1EDD>ng
## 1 1 68 1 263
## phú cuòng phú di<U+1EBF>n phu di<U+1EC1>n phú di<U+1EC1>n phú di<U+1EC1>n
## 1 1 1 1217 2
## phú Ði<U+1EC1>n phú di<U+1EC3>n phú diên phú hòa phú Hòa
## 3 1 7 2321 11
## phú k<U+1ED9>c phu l<U+1EAD>p phú l<U+1EAD>p phú L<U+1EAD>p phú l<U+1ECD>i
## 1 1 673 7 1
## phú l<U+1ED9>c phú L<U+1ED9>c PHÚ L<U+1EE2>I phú l<U+1EE3> phu l<U+1EE3>i
## 345 4 8 4 18
## phú l<U+1EE3>i phú L<U+1EE3>i phú l<U+1EE3>i[ phú lâm phú Lâp
## 27195 238 1 35 2
## phú lp<U+1EE3>i phú lý phú nfg<U+1ECD>c phu ng<U+1ECD>c phú ng<U+1ECD>c
## 1 9 2 11 22364
## phú Ng<U+1ECD>c phú NG<U+1ECD>c Phú ng<U+1ECD>c phú ng<U+1ECD>c-TT) phú ng<U+1ECD>c. A1
## 295 9 4 1 1
## phú ngoc phú ngõc phú qu<U+1ED1>c phú son phú Son
## 5 1 2 14 1
## phú t<U+1EAD>n phu tân phú tân phú Tân phù tân
## 2 5 13791 126 1
## phú th<U+1ECB>nh phú Th<U+1ECB>nh phu thanh phú thanh phú Thanh
## 304 2 1 51 1
## phú trung phu túc phú túc phú Túc phú túc.
## 5 6 1066 15 3
## phú vih phú viinh phú vin phú ving phu vinh
## 1 1 1 4 22
## phú vinh phú vinh phú Vinh phù vinh phú vinh 116
## 30077 1 301 1 5
## phú vinjh phú vnh phú vunh phú xuân phú y<U+1EBF>n
## 1 2 1 102 1
## phú yên phu`vinh phu<U+1EDB>c l<U+1ED9>c phu<U+1EDB>c long phu1 ng<U+1ECD>c
## 9 2 2 3 1
## phúl<U+1EE3>i phuong lâm phúvinh pú tân PYTe
## 2 155 1 1 1
## qu<U+1EA3>ng bình qu<U+1EA3>ng nam qu<U+1EA3>ng ngãi qu<U+1EA3>ng ninh qu<U+1EA3>ng tr<U+1ECB>
## 9 8 9 1 8
## qu<U+1EAD>n 12 quãng ngãi qui nhon r<U+1EA1>ch giá rhanh hòa
## 1 3 2 5 1
## sa déc sai gon sai gòn sài gòn saigon
## 5 1 4 316 9
## sg Sg SG singapo singapore
## 6 1 81 1 2
## sóc trang sông bé sông ray sông thao srilanka
## 45 6 3 3 1
## su<U+1ED1>i nho su<U+1ED3>i nho suôi nho tà l<U+1EA3>i tá lài
## 109 1 1 1 3
## tà lài tà Lài tai wan taiwan tân hu<U+1EC7>
## 521 1 3 61 1
## tân phong tan phú tân phú tân Phú Tân phú
## 1 4 3180 2 12
## tân phù tân phúc tân v<U+1EA1>n tánh linh tanh tùng
## 1 1 1 3 1
## tânphú tây ninh th Hóa th<U+1ECD> lâm th<U+1ED1>ng nh<U+1EA5>t
## 2 23 1 5 13
## th<U+1EE5>y di<U+1EC3>n th<U+1EE7> d<U+1EE9>c thác mai thah son thái bình
## 2 19 1 3 2
## thai lan Thailand than h son than h tùng than son
## 1 1 2 1 1
## thanh son thanh tùng thanh bình thanh hóa thanh som
## 8 1 1 36 1
## thanh son thanh Son THANH SON thanh son. thanh sonb
## 18462 131 2 1 1
## thanh stùng thanh tùng thanh Tùng thành tùng thanhn son
## 1 1101 15 1 1
## thnah hóa thnah son thnah tùng thnh son ti<U+1EC1>n giang
## 1 13 1 2 51
## tiên giang TP TQ tr<U+1EA3>ng bom tr<U+1EA3>ng bom
## 1 3 6 65 1
## tr<U+1ECB> an trà c<U+1ED5> trà C<U+1ED5> trà vinh tràng bom
## 6 48 1 31 2
## trung qu<U+1ED1>c TTd<U+1ECB>nh quán TTÐQ tthanh son túc tr<U+1EE9>ng
## 6 2 1 1 1
## túc truing túc trung Turmenistan úc Úc
## 1 398 1 1 1
## unknown usa USA USA. v<U+1EA1>n ninh
## 3 14 123 2 1
## v<U+1EC9>nh an vinh an vinh c<U+1EED>u vinh long vinh phúc
## 3 413 22 18 1
## võ d<U+1EAF>c võ su võ xu vung tàu xuân b<U+1EAF>c
## 2 1 1 49 8
## xuân hung xuân l<U+1ED9>c xuân thi<U+1EC7>n xuân tru<U+1EDD>ng
## 1 40 1 6
Bộ dữ liệu này có 229.198 dòng và 9 biến số. Biến số name và address được viết Tiếng Việt có dấu. R đọc Tiếng Việt bị lỗi nên xuất hiện nhiều kí tự khó hiểu như trên. Tôi sẽ tập trung xử lí biến số address để minh họa.
Dùng hàm count(mydf$address), kết quả chúng ta sẽ biết có 520 giá trị khác nhau được nhập vào address, trong đó có nhiều giá trị là sai lệch từ một giá trị thực, như trong ví dụ vế địa danh “Thanh Sơn” được nói ở trên.
Mục tiêu của tôi là chuẩn hóa giá trị “Thanh Sơn” và các biến thể (sai sót) nhập liệu của nó thành “thanhson” để dễ dàng phân tích. Có nhiều cách khác nhau, nhưng tôi chọn cách trước tiên đưa về chữ viết thường, loại bỏ dấu Tiếng Việt, thay thế những sai biệt, cuối cùng rút gọn thành “thanhson”.
library(stringi)
mydf$address2 <- mydf$address
# Loại bỏ dấu tiếng Việt
address2 <- stri_trans_general(mydf$address2, id="latin-ascii")
# chuyển về chữ viết thường
address2 <-tolower(address2)
table(address2)
## address2
## [hu loi [hu ngoc [phu ngoc [phu vinh 107
## 2 1 3 1 1
## africa an giang aus australia ba ria
## 1 47 1 6 11
## bac bac - la nga bac binh bac can bac giang
## 54 1 1 1 2
## bac lieu bam cat tien bao binh bao loc bau ham
## 15 1 3 66 3
## ben canh ben tre bh bien h oa bien hoa
## 2 82 11 1 203
## binh dinh binh duong binh phuoc binh thuan bo ham
## 30 133 119 132 1
## bu dang bu dop buonmathuot buu son ca mau
## 6 1 1 10 53
## cai mon cali cam my cam ranh camphuchia
## 1 1 17 1 1
## campuchia can tho cao lanh cao nguyen cat tien
## 1 24 6 1 55
## cau duong cay gao chau doc con dao cu chi
## 1 4 12 1 6
## cva d linh d0inh quan d9inh5 quan da hoai
## 3 1 4 1 20
## da kai da lat da nang da te da ton
## 10 41 8 9 2
## dac klao dac lac dac lu dac lua dac lua.
## 1 14 1 11 1
## dac nong dahoai dai loan dak lak dak nong
## 49 5 13 4 19
## dak song daklak daklua dakngo daknong
## 1 25 2 1 16
## dalat dam doi dambri dau giay dau lung
## 6 2 1 25 2
## di h5 quan di h5 quna di linh diinh quan dinh quan
## 1 1 77 2 9
## dinh qan dinh qian dinh qquan dinh quan dinh quna
## 1 3 1 40905 1
## dinh uqan dinhn quan dinhquan dnh55 quan doc mo
## 4 1 4 2 2
## dong thap dong xoai duc linh duc trong fdinh quan
## 50 23 35 11 1
## france ga canh gai canh gai gon gfia canh
## 5 2 2 1 3
## gi gia canh gia acnh gia camj gia can
## 1 2 3 5 1
## gia canh gia canh (b) gia canh 114 gia cnh gia kiem
## 26175 3 2 1 87
## gia lai gia nghia gia tan giang dien giau day
## 8 1 4 7 1
## gic canh giia canh gio linh go cong go vap
## 1 3 1 7 1
## gs ha dong ha giang ha noi ha tinh
## 1 1 4 22 7
## hai duong hai phong ham tan han quoc hanh son
## 6 2 5 11 1
## hau giang hcm hiep cuong hiep dong hiep loi
## 6 13 11 6 4
## hiep luc hiep nghia hiep nhat hiep quyet hiep tam
## 48 5 3 1 21
## hiep tam 1 hiep tam 2 hiep thuan hiep thuong hn
## 26 15 8 4 1
## ho nai hoc mon hong ngu hongkong hue
## 14 2 1 1 23
## khach xa khanh hoa kien giang kim long ko biet
## 1 4 24 2 1
## kom tum kon tum korea la bga la gi
## 1 1 11 1 1
## la gna la m6 dong la nga la nga /bt la nga 103
## 2 2 17419 1 1
## lam dong langa lao cai ld ldinh quan
## 135 1 1 1 1
## loc an loc ninh long an long giao long khanh
## 1 4 48 1 145
## long thanh long xuyen lonh khanh madagoui madagui
## 50 5 1 4 89
## malaysia mepu mien tay mien trung mui ne
## 5 1 29 3 2
## na uy nam cat tien nam cat tiuen nam dinh namcattien
## 1 209 1 7 1
## nauy nc tien nctien ngc5 dinh nghe an
## 1 1 1 1 49
## nghe tinh ngoai bac ngoc dinh ngoc 9inh5 ngoc diinh
## 2 2 5 2 2
## ngoc dinh ngoc dinh quan ngoc dinn ngoc lam nguyen hue
## 14276 4 1 12 1
## nha trang nhan co nhon trach ninh binh ninh thuan
## 8 1 29 5 9
## norway ntn ntnhiem nui huong nui tuong
## 1 60 25 2 152
## o tro o xa ohu loi ohu ngoc p loi/th dien
## 1 1 1 1 1
## p[hu loi pgu tan ph lam ph1 ngoc ph1u loi
## 1 1 1 2 1
## ph1u ngoc ph1u tan phan rang phan thiet phap
## 1 3 3 11 3
## phipl phu phu hoa phu loi phu ngoc
## 3 6 1 8 13
## phu son phu tan phu vinh phu 9ien phu an
## 1 1 3 1 23
## phu atn6 phu binh phu bung phu cinh phu cuong
## 1 68 1 1 264
## phu dien phu hoa phu koc phu lam phu lap
## 1232 2332 1 35 683
## phu lo phu loc phu loi phu loi[ phu lpoi
## 4 349 27460 1 1
## phu ly phu nfgoc phu ngoc phu ngoc-tt) phu ngoc. a1
## 9 2 22689 1 1
## phu oi phu quoc phu son phu tan phu thanh
## 1 2 15 13925 53
## phu thinh phu trung phu tuc phu tuc. phu vih
## 306 5 1087 3 1
## phu viinh phu vin phu ving phu vinh phu vinh 116
## 1 1 4 30402 5
## phu vinjh phu vnh phu vunh phu xuan phu yen
## 1 2 1 102 10
## phu`vinh phu1 ngoc phuloi phuoc loc phuoc long
## 2 1 2 2 3
## phuong lam phuvinh pu tan pyte quan 12
## 155 1 1 1 1
## quang binh quang nam quang ngai quang ninh quang tri
## 9 8 12 1 8
## qui nhon rach gia rhanh hoa sa dec sai gon
## 2 5 1 5 321
## saigon sg singapo singapore soc trang
## 9 88 1 2 45
## song be song ray song thao srilanka suoi nho
## 6 3 3 1 111
## ta lai tai wan taiwan tan hue tan phong
## 526 3 61 1 1
## tan phu tan phuc tan van tanh linh tanh tung
## 3199 1 1 3 1
## tanphu tay ninh th hoa thac mai thah son
## 2 23 1 1 3
## thai binh thai lan thailand than h son than h tung
## 2 1 1 2 1
## than son thanh son thanh tung thanh binh thanh hoa
## 1 8 1 1 36
## thanh som thanh son thanh son. thanh sonb thanh stung
## 1 18595 1 1 1
## thanh tung thanhn son thnah hoa thnah son thnah tung
## 1117 1 1 13 1
## thnh son tho lam thong nhat thu duc thuy dien
## 2 5 13 19 2
## tien giang tp tq tra co tra vinh
## 52 3 6 49 31
## trang bom tri an trung quoc ttdinh quan ttdq
## 68 6 6 2 1
## tthanh son tuc truing tuc trung turmenistan uc
## 1 1 399 1 2
## unknown usa usa. van ninh vinh an
## 3 137 2 1 416
## vinh cuu vinh long vinh phuc vo dac vo su
## 22 18 1 2 1
## vo xu vung tau xuan bac xuan hung xuan loc
## 1 49 8 1 40
## xuan thien xuan truong
## 1 6
Đến đây thì các giá trị của biến số address đã đưa về chữ viết thường, không dấu. Tuy nhiên, vẫn còn nhiều sai sót như “than h son”, “than son”, “tthanh son”, “thanh som”… Tôi sẽ thay thế những chữ viết sai như thnah, thah, thnh, than h, rhanh… bằng chữ “thanh”. Tương tự, thay các chữ sonb, som, son., bằng chữ “son” như sau:
address2 <- gsub("thnah|thah|thnh|(than h)|rhanh|thanhn|tthanh|thanhhn", "thanh", address2)
address2 <- gsub("sonb|som|son.", "son", address2)
table(address2)
## address2
## [hu loi [hu ngoc [phu ngoc [phu vinh 107
## 2 1 3 1 1
## africa an giang aus australia ba ria
## 1 47 1 6 11
## bac bac - la nga bac binh bac can bac giang
## 54 1 1 1 2
## bac lieu bam cat tien bao binh bao loc bau ham
## 15 1 3 66 3
## ben canh ben tre bh bien h oa bien hoa
## 2 82 11 1 203
## binh dinh binh duong binh phuoc binh thuan bo ham
## 30 133 119 132 1
## bu dang bu dop buonmathuot buu son ca mau
## 6 1 1 10 53
## cai mon cali cam my cam ranh camphuchia
## 1 1 17 1 1
## campuchia can tho cao lanh cao nguyen cat tien
## 1 24 6 1 55
## cau duong cay gao chau doc con dao cu chi
## 1 4 12 1 6
## cva d linh d0inh quan d9inh5 quan da hoai
## 3 1 4 1 20
## da kai da lat da nang da te da ton
## 10 41 8 9 2
## dac klao dac lac dac lu dac lua dac lua.
## 1 14 1 11 1
## dac nong dahoai dai loan dak lak dak nong
## 49 5 13 4 19
## dak son daklak daklua dakngo daknong
## 1 25 2 1 16
## dalat dam doi dambri dau giay dau lung
## 6 2 1 25 2
## di h5 quan di h5 quna di linh diinh quan dinh quan
## 1 1 77 2 9
## dinh qan dinh qian dinh qquan dinh quan dinh quna
## 1 3 1 40905 1
## dinh uqan dinhn quan dinhquan dnh55 quan doc mo
## 4 1 4 2 2
## dong thap dong xoai duc linh duc trong fdinh quan
## 50 23 35 11 1
## france ga canh gai canh gai gon gfia canh
## 5 2 2 1 3
## gi gia canh gia acnh gia camj gia can
## 1 2 3 5 1
## gia canh gia canh (b) gia canh 114 gia cnh gia kiem
## 26175 3 2 1 87
## gia lai gia nghia gia tan giang dien giau day
## 8 1 4 7 1
## gic canh giia canh gio linh go cong go vap
## 1 3 1 7 1
## gs ha dong ha giang ha noi ha tinh
## 1 1 4 22 7
## hai duong hai phong ham tan han quoc hanh son
## 6 2 5 11 1
## hau giang hcm hiep cuong hiep dong hiep loi
## 6 13 11 6 4
## hiep luc hiep nghia hiep nhat hiep quyet hiep tam
## 48 5 3 1 21
## hiep tam 1 hiep tam 2 hiep thuan hiep thuong hn
## 26 15 8 4 1
## ho nai hoc mon hong ngu hongkong hue
## 14 2 1 1 23
## khach xa khanh hoa kien giang kim long ko biet
## 1 4 24 2 1
## kom tum kon tum korea la bga la gi
## 1 1 11 1 1
## la gna la m6 dong la nga la nga /bt la nga 103
## 2 2 17419 1 1
## lam dong langa lao cai ld ldinh quan
## 135 1 1 1 1
## loc an loc ninh long an long giao long khanh
## 1 4 48 1 145
## long thanh long xuyen lonh khanh madagoui madagui
## 50 5 1 4 89
## malaysia mepu mien tay mien trung mui ne
## 5 1 29 3 2
## na uy nam cat tien nam cat tiuen nam dinh namcattien
## 1 209 1 7 1
## nauy nc tien nctien ngc5 dinh nghe an
## 1 1 1 1 49
## nghe tinh ngoai bac ngoc dinh ngoc 9inh5 ngoc diinh
## 2 2 5 2 2
## ngoc dinh ngoc dinh quan ngoc dinn ngoc lam nguyen hue
## 14276 4 1 12 1
## nha trang nhan co nhon trach ninh binh ninh thuan
## 8 1 29 5 9
## norway ntn ntnhiem nui huong nui tuong
## 1 60 25 2 152
## o tro o xa ohu loi ohu ngoc p loi/th dien
## 1 1 1 1 1
## p[hu loi pgu tan ph lam ph1 ngoc ph1u loi
## 1 1 1 2 1
## ph1u ngoc ph1u tan phan rang phan thiet phap
## 1 3 3 11 3
## phipl phu phu hoa phu loi phu ngoc
## 3 6 1 8 13
## phu son phu tan phu vinh phu 9ien phu an
## 1 1 3 1 23
## phu atn6 phu binh phu bung phu cinh phu cuong
## 1 68 1 1 264
## phu dien phu hoa phu koc phu lam phu lap
## 1232 2332 1 35 683
## phu lo phu loc phu loi phu loi[ phu lpoi
## 4 349 27460 1 1
## phu ly phu nfgoc phu ngoc phu ngoc-tt) phu ngoc. a1
## 9 2 22689 1 1
## phu oi phu quoc phu son phu tan phu thanh
## 1 2 15 13925 53
## phu thinh phu trung phu tuc phu tuc. phu vih
## 306 5 1087 3 1
## phu viinh phu vin phu ving phu vinh phu vinh 116
## 1 1 4 30402 5
## phu vinjh phu vnh phu vunh phu xuan phu yen
## 1 2 1 102 10
## phu`vinh phu1 ngoc phuloi phuoc loc phuoc long
## 2 1 2 2 3
## phuong lam phuvinh pu tan pyte quan 12
## 155 1 1 1 1
## quang binh quang nam quang ngai quang ninh quang tri
## 9 8 12 1 8
## qui nhon rach gia sa dec sai gon saigon
## 2 5 5 321 9
## sg singapo singapore soc trang son be
## 88 1 2 45 6
## son ray son thao srilanka suoi nho ta lai
## 3 3 1 111 526
## tai wan taiwan tan hue tan phong tan phu
## 3 61 1 1 3199
## tan phuc tan van tanh linh tanh tung tanphu
## 1 1 3 1 2
## tay ninh th hoa thac mai thai binh thai lan
## 23 1 1 2 1
## thailand than son thanh son thanh tung thanh binh
## 1 1 8 1 1
## thanh hoa thanh son thanh stung thanh tung tho lam
## 38 18620 1 1119 5
## thong nhat thu duc thuy dien tien giang tp
## 13 19 2 52 3
## tq tra co tra vinh trang bom tri an
## 6 49 31 68 6
## trung quoc ttdinh quan ttdq tuc truing tuc trung
## 6 2 1 1 399
## turmenistan uc unknown usa usa.
## 1 2 3 137 2
## van ninh vinh an vinh cuu vinh long vinh phuc
## 1 416 22 18 1
## vo dac vo su vo xu vung tau xuan bac
## 2 1 1 49 8
## xuan hung xuan loc xuan thien xuan truong
## 1 40 1 6
Các bạn có thể thấy kết quả tốt hơn trong phần phân tích ở trên đây. Chữ “thanh son”, có 2 space ở giữa sẽ được xóa đi một space như sau:
pat <- "[[:blank:]]{2,}" # hai hoặc nhiều hơn space
address2 <- str_replace_all(address2, pattern = pat, replace = "") # xóa đi những space, chỉ còn 1 space
Tôi sẽ làm tương tự để xóa những lỗi với các chữ khác được phát hiện ở trên:
address2 <- gsub("vih|viinh|vinjh|vnh|vunh|vinhh|vinhjh|cinh", "vinh", address2)
address2 <- gsub("nfgoc|ngoc-tt|ngoc. a1|koc", "ngoc", address2)
address2 <- gsub("ph1u|phu1|ph1|pu|ohu|pgu", "phu", address2)
address2 <- gsub("dinhn|dnh55|fdinh|diinh|di h5|d0inh|d9inh5|dinn|9inh5", "dinh", address2)
address2 <- gsub("qan|qian|qquan|quna|(uquan)", "quan", address2)
address2 <- gsub("gai|gfia|gic|giia|goa", "gia", address2)
address2 <- gsub("cnh|acnh|canhi", "canh", address2)
address2 <- gsub("aus|australia", "uc", address2)
address2 <- gsub("thailand", "thailan", address2)
address2 <- gsub("sg|hcm", "saigon", address2)
address2 <- sub("usa.", "usa", address2)
address2 <- sub("tuc.", "tuc", address2)
address2 <- sub("bga|gna", "nga", address2)
address2 <- sub("stung", "tung", address2)
address2 <- sub("ngoc)", "ngoc", address2)
address2 <- sub("bh", "bienhoa", address2)
address2 <- sub("hn", "hanoi", address2)
Nếu phát hiện ra nhiều lỗi cần sửa thì quá trình này lập lại nhiều lần, mất nhiều thời gian. Sau đó chúng ta sẽ chuyển đổi chữ “thanh son” thành chữ “thanhson” để gọn gàng và dễ dàng nhận biết hơn.
# xóa những space
mydf$address1 <- stri_replace_all(address2,"",regex="[[:blank:]]")
table(mydf$address1)
##
## [huloi [hungoc [phungoc [phuvinh 107
## 2 1 3 1 1
## africa angiang bac bac-langa bacbinh
## 1 47 54 1 1
## baccan bacgiang baclieu bamcattien baobinh
## 1 2 15 1 3
## baoloc baria bauham bencanh bentre
## 66 11 3 2 82
## bienhoa binhdinh binhduong binhphuoc binhthuan
## 215 30 133 119 132
## boham budang budop buonmathuot buuson
## 1 6 1 1 10
## caimon cali camau cammy camphuchia
## 1 1 53 17 2
## camranh cantho caolanh caonguyen cattien
## 1 24 6 1 55
## cauduong caygao chaudoc condao cuchi
## 1 4 12 1 6
## cva dacklao daclac daclu daclua
## 3 1 14 1 11
## daclua. dacnong dahoai dailoan dakai
## 1 49 25 13 10
## daklak daklua dakngo daknong dakson
## 29 2 1 35 1
## dalat dambri damdoi danang date
## 47 1 2 8 9
## daton daugiay daulung dilinh dinhquan
## 2 25 2 77 40937
## dinhuquan dlinh docmo dongthap dongxoai
## 4 1 2 50 23
## duclinh ductrong france gacanh gi
## 35 11 5 2 1
## giacamj giacan giacanh giacanh(b) giacanh114
## 5 1 26190 3 2
## giagon giakiem gialai giangdien gianghia
## 1 87 8 7 1
## giatan giauday giolinh gocong govap
## 4 1 1 7 1
## gs hadong hagiang haiduong haiphong
## 1 1 4 6 2
## hamtan hanhson hanoi hanquoc hatinh
## 5 1 23 11 7
## haugiang hiepcuong hiepdong hieploi hiepluc
## 6 11 6 4 48
## hiepnghia hiepnhat hiepquyet hieptam hieptam1
## 5 3 1 21 26
## hieptam2 hiepthuan hiepthuong hocmon honai
## 15 8 4 2 14
## hongkong hongngu hue khachxa khanhhoa
## 1 1 23 1 4
## kiengiang kimlong kobiet komtum kontum
## 24 2 1 1 1
## korea lagi lam6dong lamdong langa
## 11 1 2 135 17423
## langa/bt langa103 laocai ld ldinhquan
## 1 1 1 1 1
## locan locninh longan longgiao longkhanh
## 1 4 48 1 145
## longthanh longxuyen lonhkhanh madagoui madagui
## 50 5 1 4 89
## malaysia mephu mientay mientrung muine
## 5 1 29 3 2
## namcattien namcattiuen namdinh nauy nctien
## 210 1 7 2 2
## ngc5dinh nghean nghetinh ngiaibac ngocdinh
## 1 49 2 2 14286
## ngocdinhquan ngoclam nguyenhue nhanco nhatrang
## 4 12 1 1 8
## nhontrach ninhbinh ninhthuan norway ntn
## 29 5 9 1 60
## ntnhiem nuihuong nuituong otro oxa
## 25 2 152 1 1
## p[huloi phanrang phanthiet phap phipl
## 1 3 11 3 3
## phlam phu phu`vinh phu9ien phuan
## 1 6 2 1 23
## phuatn6 phubinh phubung phucuong phudien
## 1 68 1 264 1232
## phuhoa phulam phulap phulo phuloc
## 2333 35 683 4 349
## phuloi phuloi[ phulpoi phuly phungoc
## 27472 1 1 9 22712
## phuocloc phuoclong phuoi phuonglam phuquoc
## 2 3 1 155 2
## phuson phutan phuthanh phuthinh phutrung
## 16 13931 53 306 5
## phutuc phuvin phuving phuvinh phuvinh116
## 1090 1 4 30413 5
## phuxuan phuyen ploi/thdien pyte quan12
## 102 10 1 1 1
## quangbinh quangnam quangngia quangninh quangtri
## 9 8 12 1 8
## quinhon rachgia sadec saigon singapo
## 2 5 5 431 1
## singapore soctrang sonbe sonray sonthao
## 2 45 6 3 3
## srilanka suoinho taiwan talai tanhlinh
## 1 111 64 526 3
## tanhtung tanhue tanphong tanphu tanphuc
## 1 1 1 3201 1
## tanvan tayninh thacmai thaibinh thailan
## 1 23 1 2 2
## thanhbinh thanhhoa thanhson thanhtung thanson
## 1 38 18628 1121 1
## thhoa tholam thongnhat thuduc thuydien
## 1 5 13 19 2
## tiengiang tp tq traco trangbom
## 52 3 6 49 68
## travinh trian trungquoc ttdinhquan ttdq
## 31 6 6 2 1
## tuctruing tuctrung turmenistan uc unknown
## 1 399 1 9 3
## usa vanninh vinhan vinhcuu vinhlong
## 139 1 416 22 18
## vinhphuc vodac vosu voxu vungtau
## 1 2 1 1 49
## xuanbac xuanhung xuanloc xuanthien xuantruong
## 8 1 40 1 6
Đến đây tôi muốn tiếp tục thay thế nhiều tên gọi khác nhau của một địa danh thành một tên gọi chung của chúng. Ví dụ các địa chỉ Quận 1, Quận 2, Quận 3, Huyện Hóc Môn đều được thay bằng “HoChiMinh” để tương đồng với các tỉnh, thành phố khác.
Tôi thực hiện như sau:
address1 <- gsub("ldinhquan|hiepcuong|hiepdong|hieploi|hiepluc|hiepnghia|hiepnhat|
hiepquyet|hieptam|hieptam1|hieptam2|hiepthuan|hiepthuong", "dinhquan", mydf$address1)
address1 <- gsub("tp|traco|phuxuan|phuthinh|phuthanh|phuson|phuson|
phuonglam|phulap|phubinh|phlam|phuan|phudien|phulam|
phuloc|phu9ien|namcattien|namcattiuen|nctien", "tanphu", mydf$address1)
address1 <- gsub("vinhan", "langa", mydf$address1)
Trong dataset của tôi có những địa danh có vài chục ngàn khách hàng nhưng có những địa danh chỉ có vài khách hàng. Vì vậy, tôi muốn phân nhóm lại địa chỉ, chỉ gồm những địa phương tập trung chủ yếu khách hàng của tôi. Những địa phuong có rất ít khách hàng sẽ được đưa vào nhóm “others” cho đơn giản bảng kết quả.
Tôi recoding categorical variable như sau:
newdf <- mydf[,-c(5,8)]
mydata <- newdf %>% mutate(address = ifelse(mydf$address1 %in%
c("usa","thanhson","dinhquan", "langa", "phuloi", "phuvinh", "talai",
"phungoc", "phucuong", "tanphu", "phutan", "phutuc", "phuhoa",
"saigon", "tuctrung", "phulap", "phudien", "ngocdinh",
"lamdong","giacanh", "bienhoa", "binhduong", "binhphuoc", "namcattien",
"thanhtung", "suoinho"
),mydf$address1, "others"))
table(mydata$address)
##
## bienhoa binhduong binhphuoc dinhquan giacanh lamdong
## 215 133 119 40937 26190 135
## langa namcattien ngocdinh others phucuong phudien
## 17423 210 14286 4864 264 1232
## phuhoa phulap phuloi phungoc phutan phutuc
## 2333 683 27472 22712 13931 1090
## phuvinh saigon suoinho talai tanphu thanhson
## 30413 431 111 526 3201 18628
## thanhtung tuctrung usa
## 1121 399 139
Nếu tôi tiếp tục thủ thuật tương tự cho những địa danh có số khách hàng từ 50 đến 100 người thì nhóm “others” sẽ tiếp tục giảm thấp hơn nữa.
Đến đây tôi có thể nhìn lại những địa phương có số khách hàng nhiều nhất của tôi.
tab <- as.data.frame(table(mydata$address))
tab[order(tab$Freq, decreasing=TRUE), ]
## Var1 Freq
## 4 dinhquan 40937
## 19 phuvinh 30413
## 15 phuloi 27472
## 5 giacanh 26190
## 16 phungoc 22712
## 24 thanhson 18628
## 7 langa 17423
## 9 ngocdinh 14286
## 17 phutan 13931
## 10 others 4864
## 23 tanphu 3201
## 13 phuhoa 2333
## 12 phudien 1232
## 25 thanhtung 1121
## 18 phutuc 1090
## 14 phulap 683
## 22 talai 526
## 20 saigon 431
## 26 tuctrung 399
## 11 phucuong 264
## 1 bienhoa 215
## 8 namcattien 210
## 27 usa 139
## 6 lamdong 135
## 2 binhduong 133
## 3 binhphuoc 119
## 21 suoinho 111
Ở mức độ này, phân loại địa phương (address) là khá ổn để phân tích dữ liệu. Gồm 27 địa phương chính có số khách hàng nhiều nhất.
Bài viết này tập trung vào một vài cách cách xử lí dữ liệu dạng text, mong rằng nó hữu ích cho mọi người. Cám ơn các bạn đã dành thời gian đọc bài.