Xử lý dữ liệu chuỗi với stringr

Tác giả: Nguyen Hai Truong | 2018-09-02

Trong quá trình phân tích dữ liệu, chúng ta sẽ thường gặp phải những vấn đề liên quan đến việc xử lý text. Trong bài viết này, Ranalytics sẽ hướng dẫn các bạn sử dụng một số hàm cơ bản trong package stringr để xử lý vấn đề trên.


Stringr package

Thông thường, dữ liệu text không phải lúc nào cũng “sạch” do gặp phải những vấn đề khi nhập liệu như: lúc viết hoa, lúc viết thường, thừa nhiều dấu cách, lẫn số hoặc ký tự đặc biệt trong text… Package stringr là 1 trong những package rất hữu dụng trong R để giải quyết những vấn đề trên.

library(stringr)
library(dplyr)
library(readxl)

Chữ hoa - chữ thường

Trong một số trường hợp chúng ta muốn biểu thị text ở dạng viết hoa hoặc viết thường, chúng ta có thể dùng hàm toupper() (viết hoa), tolower() (viết thường).

# Ví dụ dữ liệu thông tin của 10 bạn học sinh
data <- data.frame(
  student = c("Nam", "Viet", "Ha", 
              "Tuan", "Ngoc ", "Quang", "Hai",
              "Son", " Dong", " duc"),
  address = c( "Ho Chi Minh", "Ha Noi ", "Hai Duong", 
               "Hai Phong", "Nghe An", 
               "Ha Tinh", "Bac Giang", 
               "Bac Ninh", 
               "Quang Binh",
               "Nha Trang"),
  dob = c("2002-12-03","2003-06-12","2003-12-20",
          "2004-06-28","2005-01-05","2005-07-15",
          "2002-01-21","2003-07-31","2005-02-06",
          "2006-08-16")
)

data$address <- data$address %>% as.character()

# Tolower giá trị của biến nơi sinh sống
tolower(data$address)
##  [1] "ho chi minh" "ha noi "     "hai duong"   "hai phong"   "nghe an"    
##  [6] "ha tinh"     "bac giang"   "bac ninh"    "quang binh"  "nha trang"
# Toupper giá trị của biến biến nơi sinh sống
toupper(data$address)
##  [1] "HO CHI MINH" "HA NOI "     "HAI DUONG"   "HAI PHONG"   "NGHE AN"    
##  [6] "HA TINH"     "BAC GIANG"   "BAC NINH"    "QUANG BINH"  "NHA TRANG"

Cat

Tuy cat không phải là hàm trong stringr nhưng là hàm rất hữu dụng khi làm việc với chuối. Để nối các chuỗi với nhau chúng ta có thể dùng hàm cat.

cat("address of student:", data$address)
## address of student: Ho Chi Minh Ha Noi  Hai Duong Hai Phong Nghe An Ha Tinh Bac Giang Bac Ninh Quang Binh Nha Trang

Chúng ta có thể thêm option sep để ngăn cách các text theo ý muốn (giả sử ở đây dùng dấu phẩy để ngăn cách giữa các chuỗi)

# Trường hợp hai
cat(data$address, sep = ",")
## Ho Chi Minh,Ha Noi ,Hai Duong,Hai Phong,Nghe An,Ha Tinh,Bac Giang,Bac Ninh,Quang Binh,Nha Trang

Subtring

Trong package stringr chúng ta có thể sử dụng hàm substr() để lấy 1 phần (đoạn) nhất định của text.

substr(x, start, stop): start - vị trí bắt đầu, stop - vị trí kết thúc.

Trong ví dụ trên, nếu chúng ta tạo thêm biến mới là biến năm sinh ta có thể lấy 4 ký tự đầu tiên của biến dob.

data %>% 
  mutate(year = substr(dob,1,4))
##    student     address        dob year
## 1      Nam Ho Chi Minh 2002-12-03 2002
## 2     Viet     Ha Noi  2003-06-12 2003
## 3       Ha   Hai Duong 2003-12-20 2003
## 4     Tuan   Hai Phong 2004-06-28 2004
## 5    Ngoc      Nghe An 2005-01-05 2005
## 6    Quang     Ha Tinh 2005-07-15 2005
## 7      Hai   Bac Giang 2002-01-21 2002
## 8      Son    Bac Ninh 2003-07-31 2003
## 9     Dong  Quang Binh 2005-02-06 2005
## 10     duc   Nha Trang 2006-08-16 2006

Gsub vs. str_replace_all

Trong r-base, chúng ta có thể sử dụng hàm gsub để loại bỏ số, ký tự đặc biệt, dấu cách thừa… trong text một cách dễ dàng.

# Tạo dataframe (trường hợp này biến address chưa được làm sạch)
data2 <- data.frame(
  student = c("Nam","Viet","Ha","Tuan","Ngoc",
  "Quang","Hai","Son","Dong","Duc"),
  address = c("Ho CHi miNh","HA NOI","Hai  Duong","Hai pHong","Nghe 12430 An","@Ha 145 Tinh","{Bac Giang}","[Bac Ninh]","(Quang Binh123#","123Nha Trang02"))

data2 
##    student         address
## 1      Nam     Ho CHi miNh
## 2     Viet          HA NOI
## 3       Ha      Hai  Duong
## 4     Tuan       Hai pHong
## 5     Ngoc   Nghe 12430 An
## 6    Quang    @Ha 145 Tinh
## 7      Hai     {Bac Giang}
## 8      Son      [Bac Ninh]
## 9     Dong (Quang Binh123#
## 10     Duc  123Nha Trang02
# Thay đổi giá trị biến address thành chữ viết hoa
data2$address <- data2$address %>% tolower
data2$address
##  [1] "ho chi minh"     "ha noi"          "hai  duong"     
##  [4] "hai phong"       "nghe 12430 an"   "@ha 145 tinh"   
##  [7] "{bac giang}"     "[bac ninh]"      "(quang binh123#"
## [10] "123nha trang02"
# Loại bỏ tất cả dấu cách
data2$address <- gsub("[[:space:]]", "", data2$address)
data2$address
##  [1] "hochiminh"      "hanoi"          "haiduong"       "haiphong"      
##  [5] "nghe12430an"    "@ha145tinh"     "{bacgiang}"     "[bacninh]"     
##  [9] "(quangbinh123#" "123nhatrang02"
# Loại bỏ số
data2$address <- gsub("\\d", "", data2$address)
data2$address
##  [1] "hochiminh"   "hanoi"       "haiduong"    "haiphong"    "nghean"     
##  [6] "@hatinh"     "{bacgiang}"  "[bacninh]"   "(quangbinh#" "nhatrang"
# Loại bỏ tất cả các ký tự đặc biệt
data2$address <- gsub("[[:punct:]]", "", data2$address)
data2$address
##  [1] "hochiminh" "hanoi"     "haiduong"  "haiphong"  "nghean"   
##  [6] "hatinh"    "bacgiang"  "bacninh"   "quangbinh" "nhatrang"
# Như vậy biến address đã được làm sạch
data2
##    student   address
## 1      Nam hochiminh
## 2     Viet     hanoi
## 3       Ha  haiduong
## 4     Tuan  haiphong
## 5     Ngoc    nghean
## 6    Quang    hatinh
## 7      Hai  bacgiang
## 8      Son   bacninh
## 9     Dong quangbinh
## 10     Duc  nhatrang

 

Sử dụng với stringr

Khi bắt đầu quen sử dụng stringr, ta hoàn toàn có thể sử dụng hàm str_replcae_all để thay thế cho gsub. Hàm này thuận tiện và đơn giản hơn so với gsub và tuân theo cấu trúc của tidyverse.

address <- c("Ho CHi miNh","HA NOI","Hai  Duong","Hai pHong","Nghe 12430 An","@Ha 145 Tinh","{Bac Giang}","[Bac Ninh]","(Quang Binh123#","123Nha Trang02")

address %>% 
  # Xóa ký tự đặc biệt
  str_replace_all("[[:punct:]]", "") %>% 
  # Xóa các số
  str_replace_all("\\d", "") %>% 
  # Xóa khoảng trắng
  str_replace_all("[[:space:]]", "") %>% 
  tolower
##  [1] "hochiminh" "hanoi"     "haiduong"  "haiphong"  "nghean"   
##  [6] "hatinh"    "bacgiang"  "bacninh"   "quangbinh" "nhatrang"

Ta hoàn toàn có thể kết hợp nhiều điều kiện như sau:

address %>% 
  str_replace_all("[[[:punct:]]\\d[[:space:]]]", 
                  "") %>% 
  tolower
##  [1] "hochiminh" "hanoi"     "haiduong"  "haiphong"  "nghean"   
##  [6] "hatinh"    "bacgiang"  "bacninh"   "quangbinh" "nhatrang"

Loại bỏ khoảng trắng trước ký tự

Trong trường hợp giả sử chúng ta chỉ muốn loại bỏ dấu cách trước và sau text mà không muốn bỏ dấu cách ngăn cách giữa các từ trong text thì chúng ta có thể sử dụng hàm str_trim()

address <- c(" Ha Noi", "HCM  ", " Hai Phong ")
address
## [1] " Ha Noi"     "HCM  "       " Hai Phong "
str_trim(address)
## [1] "Ha Noi"    "HCM"       "Hai Phong"

Như vậy, chúng ta đã vừa được làm quen với một số hàm cơ bản trong package stringr để xử lý text. Chúc các bạn học tập và làm việc hiệu quả với Ranalytics.vn!

comments powered by Disqus