Ở chương này chúng em sẽ đi sau vào cách làm việc phân tích của chuỗi khi dùng stringr và phần tích đi sau vào cách làm việc của hàm trong Stringr để xử lí cách chuỗi
Trước tiên chúng em sẽ giới thiệt về chuỗi là gì?
Chuỗi ký tự có thể xuất hiện trong tất cả các giai đoạn của dự án khoa học dữ liệu. Người dùng có thể phải xóa đầu vào chuỗi lộn xộn trước khi phân tích, trích xuất dữ liệu được nhúng trong văn bản hoặc tự động biến các kết quả dạng số thành một câu để đưa vào báo cáo. Có lẽ bản thân các chuỗi là dữ liệu quan tâm và bạn cần phát hiện và khớp các mẫu bên trong chúng Chúng em sẽ bắt đầu với một số điều cơ bản: cách nhập chuỗi trong R, cách kiểm soát cách số được chuyển đổi thành chuỗi và cuối cùng là cách kết hợp các chuỗi với nhau để tạo đầu ra kết hợp văn bản và số được định dạng độc đáo.
Chúng em sẽ bắt đầu bằng cách tìm hiểu về một số hàm stringr rất giống với một số hàm R cơ sở, sau đó là cách phát hiện các mẫu cụ thể trong chuỗi, cách tách các chuỗi thành nhiều phần cũng như cách tìm và thay thế các phần của chuỗi.
Các chức năng của Stringr đều bắt đầu bằng str_ điều này tạo điều kiện thuận lợi cho việc tìm lệnh thích hợp: Chúng ta chỉ cần nhập str_ và chức năng tự động đề xuất của Rstudio sẽ hiện thị những phần còn lại.
Đầu tiên chúng em sẽ cái đặt và gọi cói Stringr
library(stringr)
1. str_length(): Trả về một độ dài của một chuỗi bao gồm cả khoảng trắng và cả dấu chấm câu. Trong đó string là một vecto đầu vào hoặc là một vecto kí tự.
Các hàm cơ sở R có nhiều hàm để thao tác với các chuỗi, nhưng nên tránh những hàm này vì chúng khó nhớ, có một bộ nhớ tốt cho các hàm này trong gói stringr
Lấy một vectơ chuỗi làm đầu vào và trả về số lượng ký tự trong mỗi chuỗi.
str_length(c("a", "R cho khoa hoc du lieu", NA))
## [1] 1 22 NA
Chúng em sẽ gọi gói “babyname” và “dplyr” để hổ trợ cho việc phân tích chuỗi và các hàm
library(babynames)
## Warning: package 'babynames' was built under R version 4.3.1
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.1
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
Trước tiên,chúng em sẽ sử dụng gói “babynames” để gọi xử lý dữ liệu về các tên trẻ em phổ biến theo năm và giới tính
Trích vector tên con trai và tên con gái
babynames_2014 <- filter(babynames, year == 2014)
boy_names <- filter(babynames_2014, sex == "M")$name
girl_names <- filter(babynames_2014, sex == "F")$name
head(boy_names)
## [1] "Noah" "Liam" "Mason" "Jacob" "William" "Ethan"
Tìm độ dài của tất cả các tên boy_names
boy_length <- str_length(boy_names)
head(boy_length)
## [1] 4 4 5 5 7 5
Sự khác biệt về chiều dài trung bình của boy_names và girls_name
girl_length <- str_length(girl_names)
mean(girl_length) - mean(boy_length)
## [1] 0.3374758
Xác nhận hàm str_length() kiểm tra độ dài a các phần tử trong vector boy_names
head(str_length(factor(boy_names)))
## [1] 4 4 5 5 7 5
Kết luận: Độ dài trung bình của tên con gái vào năm 2014 dài hơn một ký tự khoảng một phần ba. Lưu ý rằng đây là con số trung bình ngây thơ trong đó mỗi cái tên được tính một lần, không phải theo số lượng em bé đã nhận được tên. Một phép so sánh tốt hơn có thể là trọng số trung bình của cột n trong babynames
2. Đệm chuỗi sử dụng str_pad()
Đệm chuỗi liên quan đến việc thêm các ký tự vào một chuỗi để làm cho nó có độ dài nhất định. Hàm str_pad() trong gói Stringr có thể được sử dụng để đệm chuỗi. Hàm str_pad () trả về một vectơ ký tự chứa (các) chuỗi được đệm. Dưới đây là một số tham số bạn có thể sử dụng với hàm str_pad():
Cú pháp: str_pad(string,width, side = c(“left”,“right”,“both”),pad = ““).
Trong đó:
String: chuỗi đầu vào mà chúng ta muốn đệm
width: Độ rộng mong muốn của chuỗi kết quả sau khi đệm
Side: Chỉ định đệm các chuỗi ở bên trái, bên phải hay cả hai bên
Pad: Ký tự dùng để đệm. Giá trị mặc định là khoảng trắng(” “)
Ví dụ: Thêm khoảng trắng vào một chuỗi (đối với một ký tự)
str_pad("boy_names",11,side = "both") #11:cho biet do dai sau khi them la 11
## [1] " boy_names "
Tham số pad có thể chỉ định các ký tự cần điền
str_pad("boy_names",11,side = "both",pad = "*")
## [1] "*boy_names*"
Kết hợp với gói Purrr, lập trình chức năng có thể được vector hóa để loại bỏ khoảng trắng và thêm khoảng trắng
x <- c("boy_names","girl_names")
library(purrr)
## Warning: package 'purrr' was built under R version 4.3.1
map_chr(x,str_pad,11,side = "left")
## [1] " boy_names" " girl_names"
str_c(x[seq_len(3) - 1],collapse = ",")
## [1] "boy_names,girl_names"
3. Cắt xén chuỗi sử dụng bằng str_trim( )
Cắt xén chuỗi liên quan đến việc loại bỏ các ký tự khoảng trắng ở đầu và/hoặc cuối chuỗi. Hàm str_trim() trong gói Stringr có thể được sử dụng để cắt chuỗi. Hàm str_trim() trả về một vectơ ký tự chứa (các) chuỗi đã cắt. Dưới đây là các tham số bạn có thể sử dụng với hàm str_trim():
Cú pháp:str_trim(string,side = c(“left”,“right”,“both”)).
Trong đó
string – Tham số này đại diện cho chuỗi ký tự hoặc vectơ của chuỗi sẽ được cắt bớt.
side – Tham số này chỉ định (các) bên của (các) chuỗi cần cắt. Các giá trị có thể là “cả hai”, “trái” hoặc “phải”. Giá trị mặc định là “cả hai”.
whitespace – Tham số này chỉ định các ký tự khoảng trắng cần xóa. Giá trị mặc định là “[:space:]”, khớp với bất kỳ ký tự khoảng trắng nào.
pattern – Tham số này cho phép bạn chỉ định một mẫu biểu thức chính quy để khớp các ký tự cần xóa khỏi (các) chuỗi. Giá trị mặc định là NULL, có nghĩa là tham số khoảng trắng được sử dụng để khớp với các ký tự cần loại bỏ.
fixed – Tham số này chỉ định xem tham số mẫu là một chuỗi cố định (TRUE) hay một biểu thức chính quy (FALSE). Giá trị mặc định là FALSE.
str_trim(" boy_names ")
## [1] "boy_names"
Chúng cũng có thể chỉ định phần cuối của khoảng trống cần xóa
str_trim(" boynames ",side = "left")
## [1] "boynames "
1. Trích xuất chuỗi con bằng cách sử dụng str_sub()
Trích xuất chuỗi con liên quan đến việc trích xuất một phần của chuỗi. Hàm str_sub() trong gói Stringr có thể được sử dụng để trích xuất các chuỗi con. Dưới đây là một số tham số bạn có thể sử dụng với hàm str_sub():
str_sub(string, start = 1L, end = -1L.
Trong đó:
string: là vecto đầu vào hoặc là một vecto kí tự
start: chỉ định vị trí ký tự đầu tiên trong chuỗi con sẽ được trích xuất
end: Chỉ định vị trí của ký tự cuối cùng trong các chuỗi con sẽ được trích xuất
Ví dụ: str_sub(x, 1, 3) yêu cầu chuỗi con bắt đầu từ ký tự đầu tiên, cho đến ký tự thứ ba hoặc nói cách khác là bốn ký tự đầu tiên.
x <- c("boy_names","girl_names")
str_sub(x,1,3)
## [1] "boy" "gir"
Cả bắt đầu và kết thúc đều có thể là số nguyên âm, trong trường hợp đó, chúng được tính từ cuối chuỗi. Ví dụ: str_sub(x, -3, -1), yêu cầu chuỗi con bắt đầu từ ký tự thứ tư tính từ cuối cho đến ký tự đầu tiên tính từ cuối, tức là ba ký tự cuối cùng. Một lần nữa, hãy thử với ví dụ trên:
str_sub(x,-3,-1)
## [1] "mes" "mes"
Trích xuất chữ cái đầu tiền trong boy_names và sau đó lặp bảng
boy_first_letter <- str_sub(boy_names, 1, 1)
table(boy_first_letter)
## boy_first_letter
## A B C D E F G H I J K L M N O P
## 1454 651 770 998 549 185 334 403 235 1390 1291 537 914 424 207 230
## Q R S T U V W X Y Z
## 56 778 806 771 43 160 174 56 252 379
Trích xuất chữ cái cuối cùng trong boy_names và sau đó lặp bảng
boy_last_letter <- str_sub(boy_names, -1, -1)
table(boy_last_letter)
## boy_last_letter
## a b c d e f g h i j k l m n o p
## 421 104 92 436 1148 66 82 583 705 57 349 945 389 4672 730 32
## q r s t u v w x y z
## 19 1011 826 292 81 71 34 86 697 119
Trích xuất chữ cái đầu tiền trong girl_names và sau đó lặp bảng
girl_first_letter <- str_sub(girl_names, 1, 1)
table(girl_first_letter)
## girl_first_letter
## A B C D E F G H I J K L M N O P
## 3101 699 946 810 933 209 345 469 373 1430 1694 1122 1746 752 143 303
## Q R S T U V W X Y Z
## 38 831 1369 683 28 214 85 62 294 502
Trích xUất chữ cái cuối cùng trong girl_names và sau đó lặp bảng
girl_last_letter <- str_sub(girl_names, -1, -1)
table(girl_last_letter)
## girl_last_letter
## a b c d e f g h i j k l m n o p
## 6632 20 13 81 3114 8 21 1942 1581 12 31 450 115 2608 105 3
## q r s t u v w x y z
## 2 291 326 208 59 6 17 50 1435 51
“A” là chữ cái đầu tiên phổ biến nhất cho cả bé trai và bé gái, và là chữ cái cuối cùng phổ biến nhất cho bé gái.
Tuy nhiên, chữ cái cuối cùng phổ biến nhất cho tên con trai là “n”. CHúng có thể đã thấy substr() một hàm R cơ sở tương tự như str_sub()
Ưu điểm lớn của str_sub() là khả năng sử dụng các chỉ mục âm để đếm từ cuối chuỗi.
2. str_subset(): chức năng trả về các chuỗi chứa mẫu khớp
Vì việc phát hiện các chuỗi có mẫu và sau đó sắp xếp lại các chuỗi đó là một hoạt động phổ biến, stringr cung cấp một hàm str_subset() thực hiện điều đó trong một bước. Ví dụ: hãy lặp lại tìm kiếm boy_names có chứa”zz” bằng cách sử dụng str_subset():
str_subset(boy_names, pattern = fixed("zz"))
## [1] "Uzziah" "Ozzie" "Ozzy" "Jazz" "Uzziel" "Chazz"
## [7] "Izzy" "Azzam" "Izzac" "Izzak" "Fabrizzio" "Jazziel"
## [13] "Azzan" "Izzaiah" "Muizz" "Yazziel"
Chúng ta nhận được một vectơ chuỗi mới, nhưng nó chỉ chứa các chuỗi ban đầu chứa mẫu.
str_subset() có thể dễ bị nhầm lẫn với str_extract(). str_extract() trả về một vectơ có cùng độ dài với vectơ đầu vào, nhưng chỉ với các phần của chuỗi khớp với mẫu. Tìm girl_name có chứa “U” và “z”
starts_U <- str_subset(girl_names, pattern = fixed("U"))
starts_U
## [1] "Unique" "Uma" "Unknown" "Una" "Uriah" "Ursula" "Unity"
## [8] "Umaiza" "Urvi" "Ulyana" "Ula" "Udy" "Urwa" "Ulani"
## [15] "Umaima" "Umme" "Ugochi" "Ulyssa" "Umika" "Uriyah" "Ubah"
## [22] "Umaira" "Umi" "Ume" "Urenna" "Uriel" "Urijah" "Uyen"
str_subset(starts_U, pattern = "z")
## [1] "Umaiza"
“Umamiza” là có gái có tên duy nhất bắt đầu bắt chữ “U” và chứa chữ “z”
3. Hàm str_extract() trả về một vectơ ký tự chứa (các) chuỗi con được trích xuất
Hàm này được sử dụng để trích xuất lần xuất hiện đầu tiên của một mẫu trong chuỗi ký tự hoặc vectơ của chuỗi. Hàm str_extract() trả về một vectơ ký tự chứa (các) chuỗi con được trích xuất. Dưới đây là một số tham số bạn có thể sử dụng với hàm str_extract(): Cú pháp: str_extract(string, pattern, simplify, ignore_case, opts_regex).
Trong đó:
string: Tham số này đại diện cho chuỗi ký tự hoặc vectơ của chuỗi sẽ được tách.
pattern: Tham số này chỉ định dấu phân cách hoặc mẫu biểu thức chính quy sẽ được sử dụng để tách (các) chuỗi đầu vào.
simplify: Tham số này chỉ định có đơn giản hóa kết quả thành ma trận ký tự hoặc vectơ hay không. Giá trị mặc định là FALSE.
ignore_case: Tham số này chỉ định số lần phân tách tối đa được thực hiện. Giá trị mặc định là ‘Inf’.
opts_regex: Tham số này chỉ định có nên loại bỏ các chuỗi trống trong đầu ra hay không. Giá trị mặc định là true.
Dưới đây là hai bộ dữ liệu đã được cài đặt sẳn trong gói Stringr, bao gồm fruit cho chúng ta biết 79 loại trái cây và dữ liệu sentences bao gồm 720 dòng. Chúng em sẽ dùng lệnh head() để xem 6 dòng đầu của 2 bộ dữ liệu:
fruit = stringr::fruit
head(fruit)
## [1] "apple" "apricot" "avocado" "banana" "bell pepper"
## [6] "bilberry"
head(sentences)
## [1] "The birch canoe slid on the smooth planks."
## [2] "Glue the sheet to the dark blue background."
## [3] "It's easy to tell the depth of a well."
## [4] "These days a chicken leg is a rare dish."
## [5] "Rice is often served in round bowls."
## [6] "The juice of lemons makes fine punch."
Ví dụ chúng em muốn trích xuất các từ có trái cây trong câu
fruit_match <- str_c(fruit, collapse = "|")
fruit_match
## [1] "apple|apricot|avocado|banana|bell pepper|bilberry|blackberry|blackcurrant|blood orange|blueberry|boysenberry|breadfruit|canary melon|cantaloupe|cherimoya|cherry|chili pepper|clementine|cloudberry|coconut|cranberry|cucumber|currant|damson|date|dragonfruit|durian|eggplant|elderberry|feijoa|fig|goji berry|gooseberry|grape|grapefruit|guava|honeydew|huckleberry|jackfruit|jambul|jujube|kiwi fruit|kumquat|lemon|lime|loquat|lychee|mandarine|mango|mulberry|nectarine|nut|olive|orange|pamelo|papaya|passionfruit|peach|pear|persimmon|physalis|pineapple|plum|pomegranate|pomelo|purple mangosteen|quince|raisin|rambutan|raspberry|redcurrant|rock melon|salal berry|satsuma|star fruit|strawberry|tamarillo|tangerine|ugli fruit|watermelon"
has_fruit <- str_subset(sentences, fruit_match)
matches <- str_extract(has_fruit, fruit_match)
head(matches)
## [1] "lemon" "fig" "pear" "peach" "fig" "fig"
str_extract() chỉ trích xuất kết quả khớp đầu tiên, nên em sẽ sử dụng str_extract_all() để trích xuất tất cả các kết quả khớp, kết quả được hiển thị trong danh sách
str_extract_all(has_fruit,fruit_match) %>% head()
## [[1]]
## [1] "lemon"
##
## [[2]]
## [1] "fig"
##
## [[3]]
## [1] "pear"
##
## [[4]]
## [1] "peach"
##
## [[5]]
## [1] "fig"
##
## [[6]]
## [1] "fig" "apple"
Tiếp theo chúng em sẽ Đơn giản hóa = TRUE trả về một ma trận
str_extract_all(has_fruit,fruit_match,simplify = T) %>% head()
## [,1] [,2]
## [1,] "lemon" ""
## [2,] "fig" ""
## [3,] "pear" ""
## [4,] "peach" ""
## [5,] "fig" ""
## [6,] "fig" "apple"
Bây giờ chúng em sẽ lấy ví dụ trong bộ dữ liệu sentences để giải thích về hàm str_match
Lấy tất cả các danh từ trong câu có “a” hoặc “the” đẻ làm từ định lượng
danhtu <- "(a|the) ([^ ]+)"
has_danhtu <- sentences %>%
str_subset(danhtu) %>%
head(10)
has_danhtu %>%
str_extract(danhtu)
## [1] "the smooth" "the sheet" "the depth" "a chicken" "the parked"
## [6] "the sun" "the huge" "the ball" "the woman" "a helps"
str_match() khác với str_extract(), chủ yếu là vì str_match() sẽ trả về mọi nội dung đã chụp
Trích xuất phần khớp với mẫu trong mỗi danh từ
danhtu <- "(a|the) ([^ ]+)"
has_danhtu <- sentences %>%
str_subset(danhtu) %>%
head(10)
has_danhtu %>%
str_match(danhtu)
## [,1] [,2] [,3]
## [1,] "the smooth" "the" "smooth"
## [2,] "the sheet" "the" "sheet"
## [3,] "the depth" "the" "depth"
## [4,] "a chicken" "a" "chicken"
## [5,] "the parked" "the" "parked"
## [6,] "the sun" "the" "sun"
## [7,] "the huge" "the" "huge"
## [8,] "the ball" "the" "ball"
## [9,] "the woman" "the" "woman"
## [10,] "a helps" "a" "helps"
1. Khớp mẫu sử dụng str_detect( )
Khớp mẫu liên quan đến việc tìm một chuỗi con khớp với một mẫu cụ thể. Hàm str_detect() trong gói Stringr có thể được sử dụng để phát hiện các mẫu trong chuỗi. Dưới đây là một số tham số bạn có thể sử dụng với hàm str_detect() :
Cú pháp: str_detect(string, pattern, negate ): Có chức năng kiểm tra xem một chuỗi có chứa một mẫu hay không và kết quả trả về là “TRUE” hoặc “FALSE”
string: Đại diện cho chuỗi ký tự hoặc vecto của chuỗi muốn phát hiện trong mẫu đó
pattern: Tham số này chỉ định mẫu hoặc biểu thức chính quy sẽ được phát hiện trong chuỗi đầu vào
negate: Tham số này chỉ định có trả về phần bù logic của kết quả phát hiện hay không
Kiểm tra xem một vectơ ký tự có khớp với một mẫu hay không, trả về một vectơ logic
x <- c("boy_names","girl_names")
str_detect(x,"o")
## [1] TRUE FALSE
Một ứng dụng phổ biến là sử dụng véc tơ logic thu được để thu được các phần tử con phù hợp
x[str_detect(x,"e")]
## [1] "boy_names" "girl_names"
Kiểm tra xem mỗi phần tử trong vector boy_names có chứa chuỗi “zz” hay không?
contains_zz <- str_detect(boy_names, pattern = "zz")
str(contains_zz)
## logi [1:14047] FALSE FALSE FALSE FALSE FALSE FALSE ...
Có bao nhiêu tên chứa “zz”?
sum(contains_zz)
## [1] 16
Tên nào có chứa “zz”
boy_names[contains_zz]
## [1] "Uzziah" "Ozzie" "Ozzy" "Jazz" "Uzziel" "Chazz"
## [7] "Izzy" "Azzam" "Izzac" "Izzak" "Fabrizzio" "Jazziel"
## [13] "Azzan" "Izzaiah" "Muizz" "Yazziel"
Hàng nào trong boy_df có tên chứa “zz” ?
boy_df <- filter(babynames_2014, sex == "M")
boy_df[contains_zz,]
## # A tibble: 16 × 5
## year sex name n prop
## <dbl> <chr> <chr> <int> <dbl>
## 1 2014 M Uzziah 67 0.0000328
## 2 2014 M Ozzie 62 0.0000303
## 3 2014 M Ozzy 57 0.0000279
## 4 2014 M Jazz 21 0.0000103
## 5 2014 M Uzziel 21 0.0000103
## 6 2014 M Chazz 17 0.00000832
## 7 2014 M Izzy 16 0.00000783
## 8 2014 M Azzam 14 0.00000685
## 9 2014 M Izzac 13 0.00000636
## 10 2014 M Izzak 8 0.00000391
## 11 2014 M Fabrizzio 7 0.00000342
## 12 2014 M Jazziel 6 0.00000293
## 13 2014 M Azzan 5 0.00000245
## 14 2014 M Izzaiah 5 0.00000245
## 15 2014 M Muizz 5 0.00000245
## 16 2014 M Yazziel 5 0.00000245
Ví dụ cuối cùng đó là một cách sử dụng phổ biến khác của str_detect() đặt khung dữ liệu thành các hàng trong đó các giá trị trong cột chứa mẫu quan tâm.
Trong trường hợp này, nó cho chúng ta thấy rằng những tên có chứa zz này khá hiếm. Ví dụ, ngay cả cậu bé nổi tiếng nhất, Uzziah, cũng chỉ chiếm 0,003% trong số các cậu bé sinh năm 2014.
2. Chức năng định vị kí tự bằng hàm str_locate()
str_locate() Trả về vị trí đầu tiên và cuối cùng của đối tượng phù hợp, thường được sử dụng cùng với hàm str_sub
x <- c("boy_names","girl_names")
str_locate_all(x,'a')
## [[1]]
## start end
## [1,] 6 6
##
## [[2]]
## start end
## [1,] 7 7
Gói stringr cung cấp phương thức str_count() được sử dụng để đếm số lần xuất hiện của một mẫu nhất định được chỉ định làm đối số cho hàm. Mẫu có thể là một ký tự đơn hoặc một nhóm ký tự. Bất kỳ trường hợp nào khớp với biểu thức đều dẫn đến sự gia tăng của số đếm. Phương thức này cũng có thể được gọi trên một vectơ chuỗi và một vectơ đếm riêng lẻ được trả về có chứa các số lượng riêng lẻ của số lượng mẫu phù hợp được tìm thấy.
Cú pháp:str_count(str, pattern = “”) Trong đó:
str: Chuỗi để đếm số lần xuất hiện của pattern: mẫu phù hợp với
str_count() hàm này sẽ trả về số lượng kết quả khớp trong mỗi chuỗi
x <- c("boy_names","girl_names")
str_count(x, "a")
## [1] 1 1
Đếm số lần xuất hiện của “a” và “A” trong girl_names và tạo biểu đồ số của cả 2
number_as <- str_count(girl_names, pattern = fixed("a"))
number_As <- str_count(girl_names, pattern = fixed("A"))
hist(number_as)
hist(number_As)
Tìm tổng của “a” và “A”
total_as <- number_As + number_as
girl_names[total_as > 4]
## [1] "Aaradhana"
1. Nối chuỗi sử dụng str_c( )
Nối chuỗi là quá trình nối hai hoặc nhiều chuỗi lại với nhau. Hàm str_c() trong gói Stringr có thể được sử dụng để nối chuỗi. Hàm str_c() rất dễ sử dụng và cung cấp nhiều tham số khác nhau để tùy chỉnh quy trình nối. Dưới đây là một số tham số bạn có thể sử dụng với hàm str_c():
c là viết tắt của concatenate, một hàm hoạt động giống như paste() Nó lấy các vectơ của chuỗi làm đầu vào cùng với các đối số sep và collapse.
Cú pháp :str_c(…, sep, collapse, ignore_na, trim)
Trong đó:
. . . – Tham số này đại diện cho các chuỗi cần được nối. Bạn có thể chỉ định bất kỳ số lượng đối số nào được phân tách bằng dấu phẩy.
sep – Tham số này chỉ định dấu phân cách được sử dụng giữa các chuỗi được nối. Dấu phân cách mặc định là một chuỗi rỗng.
collapse - Tham số này được sử dụng để thu gọn đầu ra của str_c() thành một chuỗi. Giá trị mặc định là FALSE.
ignore_na – Tham số này được sử dụng để bỏ qua mọi giá trị bị thiếu trong chuỗi đầu vào. Giá trị mặc định là FALSE.
trim – Tham số này được sử dụng để cắt bất kỳ ký tự khoảng trắng nào từ đầu hoặc cuối mỗi chuỗi trước khi nối chúng. Giá trị mặc định là FALSE.
Hợp nhất nhiều chuỗi thành một chuỗi
str_c("x","y","z")
## [1] "xyz"
Chỉ định tham số sep để xác định dấu phân cách
str_c("x","y",sep = ", ")
## [1] "x, y"
Chỉ định collapse để kết hợp các đối số vectơ thành một chuỗi lớn
str_c(head(letters),collapse = ",")
## [1] "a,b,c,d,e,f"
str_c(c('a','a1'),c('b','b1'),collapse='-')
## [1] "ab-a1b1"
str_c() là một hàm được vector hóa để tái chế các vectơ ký tự có độ dài ngắn
str_c("prefix-",c('a','b','c'),"-suffix")
## [1] "prefix-a-suffix" "prefix-b-suffix" "prefix-c-suffix"
Kết hợp một vectơ ký tự thành một chuỗi, sử dụng đối số thu gọn
str_c(c("x","y","z"),collapse = ",")
## [1] "x,y,z"
Hoạt động này là tốt bởi vì bạn tìm hiểu nhanh chóng khi bạn có thể thiếu các giá trị, thay vì phát hiện ra các “NA” kỳ lạ sau đó bên trong chuỗi của bạn.
2. Tách chuỗi bằng cách sử dụng str_split() Sử dụng str_split() để phân tách chuỗi thành nhiều phần và trả về một danh sách. Bạn cũng có thể chỉ định Simple = TRUE để trả về một ma trận
sentences %>%
head(5) %>%
str_split(" ")
## [[1]]
## [1] "The" "birch" "canoe" "slid" "on" "the" "smooth"
## [8] "planks."
##
## [[2]]
## [1] "Glue" "the" "sheet" "to" "the"
## [6] "dark" "blue" "background."
##
## [[3]]
## [1] "It's" "easy" "to" "tell" "the" "depth" "of" "a" "well."
##
## [[4]]
## [1] "These" "days" "a" "chicken" "leg" "is" "a"
## [8] "rare" "dish."
##
## [[5]]
## [1] "Rice" "is" "often" "served" "in" "round" "bowls."
Tách both_names thành first_names và last_names
both_names <- c("Box, George", "Cox, David")
both_names_split <- str_split(both_names, pattern = fixed(", "), simplify = TRUE)
first_names <- both_names_split[, 2]
last_names <- both_names_split[, 1]
Ngoài ra sử dụng đối số đơn giản hóa = TRUE khi chúng ta muốn chia mỗi chuỗi thành các phần bằng nhau.
_ Đơn giản hóa =True
Nói chung, việc chỉ định đơn giản hóa = TRUE sẽ cung cấp cho chúng ta đầu ra dễ làm việc hơn, nhưng chúng ta sẽ luôn nhận được n phần (ngay cả khi một số phần trống, ““).
Đôi khi, chúng ta muốn biết một chuỗi có thể được chia thành bao nhiêu phần hoặc muốn làm gì đó với mỗi phần trước khi chuyển sang cấu trúc đơn giản hơn. Đây là tình huống mà chúng ta không muốn đơn giản hóa và sẽ phải xử lý đầu ra bằng thứ gì đó như lapply().
Để thực hiện các phép tính này, chúng ta cần chia các dòng thành các từ. Một cách để chia câu thành các từ là chia trên khoảng trống ” “. Điều này hơi khó khăn vì, ví dụ, nó sẽ không nhận các từ được phân tách bằng một chuỗi thoát dòng mới như trong”hai“, nhưng vì tình huống này không xảy ra trong các dòng của bạn, nên nó sẽ làm
Sau đây chúng em sẽ lấy dữ liệu sentences để thực hiện một số thống kê văn bản đơn giản trên các dòng của mình. Mục tiêu của chúng em là tính xem có bao nhiêu từ trong mỗi dòng và độ dài trung bình của các từ trong mỗi dòng.
Số từ trong mỗi dòng
lines <- head(sentences)
words <- str_split(lines, pattern = fixed(" "))
lapply(words, length)
## [[1]]
## [1] 8
##
## [[2]]
## [1] 8
##
## [[3]]
## [1] 9
##
## [[4]]
## [1] 9
##
## [[5]]
## [1] 7
##
## [[6]]
## [1] 7
Độ dài trung bình trên mỗi dòng
word_lengths <- lapply(words, str_length)
lapply(word_lengths, mean)
## [[1]]
## [1] 4.375
##
## [[2]]
## [1] 4.5
##
## [[3]]
## [1] 3.333333
##
## [[4]]
## [1] 3.555556
##
## [[5]]
## [1] 4.285714
##
## [[6]]
## [1] 4.428571
Kết luận: Độ dài từ không hoàn toàn đúng vì nó đã bao gồm một số ký hiệu dấu chấm câu. Để giải quyết vấn đề đó chúng ta thay thế chúng trước bằng hàm str_replace() sẽ được chúng em giới thiệu phần sau.
Đôi khi, việc thay thế các phần chúng ta không muốn bằng một chuỗi rỗng ” ” sẽ dễ dàng hơn. Đây cũng là một phương pháp phổ biến để dọn dẹp chuỗi, chẳng hạn như để xóa dấu chấm câu hoặc khoảng trắng không mong muốn.
str_replace() và str_replace_all() cho phép chúng ta thay thế các kết quả khớp để tạo chuỗi mới
str_replace(string, pattern = ’‘, replacement =’’): Thay thế ký tự liên quan đến viêc thay thế một chuỗi con trong một chuỗi bằng một chuỗi con khác. Trong đó:
string: Tham số này đại diện cho chuỗi ký tự hoặc một vecto chuỗi muốn thay thế các mẫu trong đó
pattern: Tham số này chỉ định mẫu hoặc biểu thức chính quy sẽ được thay thế cho các chuỗi đầu vào.
replacement: Tham số này chỉ định các chuỗi thay thế sẽ được thay thế cho các mẫu trong các chuỗi đầu vào
Đầu tiên chúng em sẽ thực hiện thay thế các nguyên âm (a, e, i, o, u) trong các chuỗi “apple”, “pear” và “banana” bằng dấu gạch ngang “-”
x <- c("apple", "pear", "banana")
str_replace(x, "[aeiou]", "-")
## [1] "-pple" "p-ar" "b-nana"
Thay tế tất cả các ký tự trong chuỗi bằng str_replace_all
str_replace_all(x, "[aeiou]", "-")
## [1] "-ppl-" "p--r" "b-n-n-"
Với str_replace_all() chúng em cũng có thể cung cấp một vectơ có tên cho nhiều lần thay thế
x <- c("1 house", "2 cars", "3 people")
str_replace_all(x, c("1" = "one", "2" = "two", "3" = "three"))
## [1] "one house" "two cars" "three people"
Trong quá trình thay thế, chúng ta cũng có thể được kết hợp
sentences %>%
str_replace("([^ ]+) ([^ ]+) ([^ ]+)", "\\1 \\3 \\2") %>%
head(5)
## [1] "The canoe birch slid on the smooth planks."
## [2] "Glue sheet the to the dark blue background."
## [3] "It's to easy tell the depth of a well."
## [4] "These a days chicken leg is a rare dish."
## [5] "Rice often is served in round bowls."
Đây chính là mẫu biểu thức chính quy để tìm các đoạn câu trong danh sách sentences có ba từ, đổi chỗ vị trí giữa từ thứ hai và thứ ba trong mỗi đoạn câu.Chúng em sẽ giải thích rõ ở phần sau biểu thức chính quy
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 như sau:
Ví dụ lấy dữ liệu về trái cây
fruit <- c("apple", "pear", "banana")
str_to_lower(): chuyển đổi tất cả các chữ cái trong chuỗi thành chữ thường
str_to_lower(fruit)
## [1] "apple" "pear" "banana"
str_to_upper(): chuyển đổi tất cả các chữ cái trong chuỗi đầu vào thành chữ hoa
str_to_upper(fruit)
## [1] "APPLE" "PEAR" "BANANA"
str_to_title(): Chuyển đổi các ký tự đầu tiên của mỗi từ trong một chuỗi thành chữ hoa (in hoa), trong khi giữ lại các ký tự còn lại ở dạng chữ thường (in thường).
str_to_title(fruit)
## [1] "Apple" "Pear" "Banana"
Biểu thức chính quy có thể hiểu là một chuỗi các ký tự khớp với một mẫu trong một đoạn văn bản hoặc một tệp văn bản. Nó được sử dụng trong khai thác văn bản trong rất nhiều ngôn ngữ lập trình. Các ký tự của biểu thức chính quy khá giống nhau trong tất cả các ngôn ngữ. Nhưng các chức năng trích lọc, định vị, phát hiện và thay thế có thể khác nhau ở các ngôn ngữ khác nhau.
Trong phần này, chúng em sẽ tìm hiểu về biểu thức chính quy, một ngôn ngữ để mô tả các mẫu trong chuỗi. Bằng cách kết hợp các biểu thức chính quy với các hàm stringr, giúp sẽ tăng đáng kể khả năng thao tác các chuỗi của mình.
Rebus cung cấp các phím tắt START và END để chỉ định các biểu thức chính quy khớp với phần đầu và phần cuối của chuỗi. Chúng còn được gọi là neo. Bạn có thể dùng thử chỉ bằng cách gõ
• str_view() và str_view_all(): Hai hàm này dùng để học biểu thức chính quy
KHớp các chữ bằng chữ “an”
library(rebus)
## Warning: package 'rebus' was built under R version 4.3.1
##
## Attaching package: 'rebus'
## The following object is masked from 'package:stringr':
##
## regex
x <- c("apple", "banana", "pear")
str_view(x,"an")
## [2] │ b<an><an>a
” . ” Có thể đại diện cho bất kỳ ký tự nào, ngoại trừ dòng mới
str_view(x,".a.")
## [2] │ <ban>ana
## [3] │ p<ear>
Nếu bạn muốn khớp với ký tự “.”, bạn cần thoát ký tự đó (bảo R chỉ khớp với ” .” và loại bỏ tính năng khớp của “.”)
str_view(c("abc","a.c","bef"),"a\\.c")
## [2] │ <a.c>
Nếu bạn muốn khớp , bạn cần sử dụng \\ để khớp
str_view(c("a\\c","abc"),"\\\\")
## [1] │ a<\>c
^ khớp với phần đầu của ký tự $ khớp với cuối ký tự
x <- c("apple","banana")
str_view(x,"^a")
## [1] │ <a>pple
str_view(x,"a$")
## [2] │ banan<a>
Để khớp một ký tự hoàn chỉnh, hãy sử dụng cả ^ và $
x <- c("apple pie", "apple", "apple cake")
str_view(x,"^apple$")
## [2] │ <apple>
Giống như các biểu thức chính quy trong các ngôn ngữ khác, sự khác biệt trong cách sử dụng là bạn cần sử dụng hai dấu gạch chéo
x <- c("1","a1w")
str_view(x,"^\\d$")
## [1] │ <1>
-Tương tự như biểu thức chính quy khác R cũng có Số lần lập lại Nhóm và phản hồi(chú ý đến việc sử dụng phản hồi gạch chéo kép)
x <- c("abab","abba")
str_view(x,"(..)\\1")
## [1] │ <abab>
Trên đây là phần cơ bản về biểu thức chính quy trong R, sau này chúng ta sẽ tìm hiểu cách sử dụng chúng để giải quyết các bài toán thực tế, các hàm do gói stringr triển khai như sau: Xác định cái nào phù hợp với mẫu Tìm nơi mẫu phù hợp Trích xuất nội dung phù hợp Thay thế phần phù hợp Tách một chuỗi dựa trên một trận đấu Chúng ta sẽ chứng mình những điều đó vào phần sau
Trong các biểu thức chính quy, một lớp ký tự là một cách chỉ định “khớp một (và chỉ một) trong số các ký tự sau”.
Trong rebus, chúng ta có thể chỉ định tập hợp các ký tự được phép sử dụng hàm char_class().
x <- c("grey sky", "gray elephant")
str_view(x, pattern = "gr" %R% char_class("ae") %R% "y")
## [1] │ <grey> sky
## [2] │ <gray> elephant
Lớp ký tự phủ định khớp với “bất kỳ ký tự đơn nào không thuộc một trong các ký tự sau” và trong rebus được chỉ định bằng negated_char_class()
Không giống như ở những nơi khác trong một biểu thức chính quy, bạn không cần thoát khỏi các ký tự có thể có ý nghĩa đặc biệt bên trong các lớp ký tự. Nếu bạn muốn phù hợp. bạn có thể bao gồm . trực tiếp, v.d. char_class(“..”). Ghép một - phức tạp hơn một chút. Nếu bạn cần làm điều đó, chỉ cần đảm bảo rằng nó xuất hiện đầu tiên trong lớp nhân vật.
Tạo lớp kí tự chỉ chứa nguyên âm
vowels <- char_class("aeiouAEIOU")
vowels
## <regex> [aeiouAEIOU]
x <- c("ow", "ooh", "yeeeah!", "shh")
str_view(x, pattern = one_or_more(vowels))
## [1] │ <o>w
## [2] │ <oo>h
## [3] │ y<eeea>h!
Bạn sẽ thấy chúng ta có thể ghép o trong ow đơn, o kép trong ooh và chuỗi es theo sau bởi a trong yeeeah, nhưng không có gì trong shh vì không có một nguyên âm nào.
Ngược lại, zero_or_more() sẽ khớp ngay cả khi không có sự cố nào xảy ra, hãy thử
str_view(x, pattern = zero_or_more(vowels))
## [1] │ <o><>w<>
## [2] │ <oo><>h<>
## [3] │ <>y<eeea><>h<>!<>
## [4] │ <>s<>h<>h<>
Vì cả yeeeah và shh đều bắt đầu không có nguyên âm, nên chúng khớp với “không có nguyên âm” và vì biểu thức chính quy lười biếng nên chúng không cần tìm đâu xa và trả về phần đầu của chuỗi dưới dạng khớp.
Xem tên chỉ có Nguyên âm
# Vowels from last exercise
vowels <- char_class("aeiouAEIOU")
# Use `negated_char_class()` for everything but vowels
not_vowels <- negated_char_class("aeiouAEIOU")
# See names with only vowels
str_view(boy_names,
pattern = exactly(one_or_more(vowels)),
match = TRUE)
## [10019] │ <Io>
Xem tên không có nguyên âm
str_view(boy_names,
pattern = exactly(one_or_more(not_vowels)),
match = TRUE)
## [425] │ <Ty>
## [485] │ <Rhys>
## [658] │ <Flynn>
## [1385] │ <Sky>
## [1679] │ <Fynn>
## [1769] │ <Kyng>
## [2004] │ <Cy>
## [2254] │ <Wynn>
## [2624] │ <Cj>
## [2974] │ <Tj>
## [3404] │ <Jc>
## [3656] │ <Ky>
## [3837] │ <Jr>
## [3861] │ <Rhythm>
## [4496] │ <Rj>
## [4628] │ <Md>
## [4775] │ <Kc>
## [5351] │ <Jj>
## [5606] │ <Lynn>
## [5921] │ <Rylyn>
## ... and 33 more
.
.
.
.