10 Ký tự và chuỗi

Chương này trình bày việc sử dụng package stringr để đánh giá và xử lý các giá trị ký tự (“chuỗi”).

  1. Các hàm kết hợp, thiết lập thứ tự, phân tách, sắp xếp - str_c(), str_glue(), str_order(), str_split()

  2. Làm sạch và chuẩn hóa

    • Các hàm điều chỉnh độ dài ký tự - str_pad(), str_trunc(), str_wrap()
    • Các hàm thay đổi chữ hoa/chữ thường - str_to_upper(), str_to_title(), str_to_lower(), str_to_sentence()
  3. Các hàm đánh giá và trích xuất vị trí - str_length(), str_sub(), word()

  4. Các hàm làm việc với patterns

    • Phát hiện và định vị - str_detect(), str_subset(), str_match(), str_extract()
    • Sửa đổi và thay thế - str_sub(), str_replace_all()
  5. Biểu thức chính quy (“regex”)

Để dễ hiển thị, hầu hết các code ví dụ đều mô phỏng trên một vectơ ngắn dạng ký tự đã được xác định, tuy nhiên chúng có thể dễ dàng áp dụng trên một cột trong bộ dữ liệu.

Package stringr vignette đã cung cấp nhiều ý tưởng cho chương này.

10.1 Chuẩn bị

Gọi packages

Cài đặt hoặc gọi package stringr và các packages tidyverse khác.

# install/load packages
pacman::p_load(
  stringr,    # many functions for handling strings
  tidyverse,  # for optional data manipulation
  tools)      # alternative for converting to title case

Nhập dữ liệu

Để bắt đầu, chúng ta nhập bộ dữ liệu có tên linelist đã làm sạch bao gồm các trường hợp từ vụ dịch Ebola mô phỏng. Để tiện theo dõi, bấm để tải dữ liệu linelist “đã được làm sạch” (dưới dạng tệp .rds). Nhập dữ liệu bằng hàm import() từ package rio (nó xử lý nhiều loại tệp như .xlsx, .csv, .rds - xem thêm chương Nhập xuất dữ liệu để biết thêm chi tiết).

# import case linelist 
linelist <- import("linelist_cleaned.rds")

50 hàng đầu tiên của bộ dữ liệu linelist được hiển thị bên dưới.

10.2 Hợp nhất, tách, và sắp xếp

Chương này bao gồm:

  • Sử dụng hàm str_c(), str_glue(), và unite() để ghép nối ký tự
  • Sử dụng hàm str_order() để sắp xếp ký tự
  • Sử dụng hàm str_split()separate() để phân tách ký tự

Kết hợp các chuỗi ký tự

Để kết hợp hoặc nối nhiều chuỗi ký tự thành một chuỗi ký tự, chúng tôi khuyên bạn nên sử dụng hàm str_c từ stringr. Nếu bạn có các giá trị ký tự riêng biệt để kết hợp, đơn giản chỉ cần cung cấp chúng dưới dạng đối số, được phân tách bằng dấu phẩy.

str_c("String1", "String2", "String3")
## [1] "String1String2String3"

Đối số sep = chèn một giá dạng trị ký tự vào giữa mỗi đối số ký tự bạn cung cấp (ví dụ: chèn dấu phẩy, dấu cách hoặc dòng mới "\n")

str_c("String1", "String2", "String3", sep = ", ")
## [1] "String1, String2, String3"

Đối số collapse = có liên quan nếu bạn đang nhập nhiều vectơ làm đối số cho hàm str_c(). Nó được sử dụng để tách các phần tử của một vectơ kết quả, sao cho vectơ kết quả chỉ là một phần tử chứa ký tự dài.

Ví dụ dưới đây cho thấy sự kết hợp của hai vectơ thành một (tên và họ). Một ví dụ tương tự khác có thể là các phạm vi địa chính và số lượng trường hợp. Trong ví dụ này:

  • Giá trị sep = xuất hiện giữa từng họ và tên
  • Giá trị collapse = xuất hiện giữa tên từng người
first_names <- c("abdul", "fahruk", "janice") 
last_names  <- c("hussein", "akinleye", "okeke")

# sep displays between the respective input strings, while collapse displays between the elements produced
str_c(first_names, last_names, sep = " ", collapse = ";  ")
## [1] "abdul hussein;  fahruk akinleye;  janice okeke"

Lưu ý: Tùy thuộc vào trường hợp hiển thị mong muốn, khi in một chuỗi kết hợp như vậy với các dòng mới, bạn có thể cần phải đặt toàn bộ cụm từ trong hàm cat() để các dòng mới được in đúng cách:

# For newlines to print correctly, the phrase may need to be wrapped in cat()
cat(str_c(first_names, last_names, sep = " ", collapse = ";\n"))
## abdul hussein;
## fahruk akinleye;
## janice okeke

Chuỗi động

Sử dụng hàm str_glue() để chèn đoạn code động của R vào chuỗi ký tự. Đây là một hàm hữu dụng để tạo tiêu đề biểu đồ động, như được mô tả dưới đây:

  • Tất cả nội dung nằm giữa dấu ngoặc kép str_glue("")
  • Bất kỳ đoạn code động hoặc tham chiếu nào đến các giá trị được xác định trước đều được đặt trong dấu ngoặc nhọn {}, bên trong dấu ngoặc kép. Có thể có nhiều dấu ngoặc nhọn trong cùng một câu lệnh str_glue().
  • Để hiển thị dấu ngoặc kép ", hãy sử dụng dấu ngoặc đơn bên trong dấu ngoặc kép (ví dụ: khi cung cấp định dạng ngày - xem ví dụ bên dưới)
  • Mẹo: Bạn có thể sử dụng \n để bắt buộc xuống một dòng mới
  • Mẹo: Bạn có thể sử dụng hàm format() để điều chỉnh hiển thị ngày và sử dụng hàm Sys.Date() để hiển thị ngày hiện tại.

Một ví dụ đơn giản về tiêu đề biểu đồ động:

str_glue("Data include {nrow(linelist)} cases and are current to {format(Sys.Date(), '%d %b %Y')}.")
## Data include 5888 cases and are current to 14 Oct 2021.

Một định dạng thay thế là sử dụng trình giữ chỗ (placeholder) bên trong dấu ngoặc kép và chỉ định chúng trong các đối số ở phía sau trong hàm str_glue() như bên dưới. Việc này sẽ làm tăng tính tường minh cho code nếu phần văn bản dài.

str_glue("Linelist as of {current_date}.\nLast case hospitalized on {last_hospital}.\n{n_missing_onset} cases are missing date of onset and not shown",
         current_date = format(Sys.Date(), '%d %b %Y'),
         last_hospital = format(as.Date(max(linelist$date_hospitalisation, na.rm=T)), '%d %b %Y'),
         n_missing_onset = nrow(linelist %>% filter(is.na(date_onset)))
         )
## Linelist as of 14 Oct 2021.
## Last case hospitalized on 30 Apr 2015.
## 256 cases are missing date of onset and not shown

Kéo từ bộ dữ liệu

Đôi khi, sẽ rất hữu ích khi lấy dữ liệu từ một bộ dữ liệu và dán chúng lại với nhau theo trình tự. Dưới đây là một ví dụ về bộ dữ liệu. Chúng ta sẽ sử dụng cách này để có một phát biểu tóm tắt về các khu vực pháp lý, cũng như số ca mắc mới và tổng số ca.

# make case data frame
case_table <- data.frame(
  zone        = c("Zone 1", "Zone 2", "Zone 3", "Zone 4", "Zone 5"),
  new_cases   = c(3, 0, 7, 0, 15),
  total_cases = c(40, 4, 25, 10, 103)
  )

Sử dụng hàm str_glue_data(), được thiết kế để lấy dữ liệu từ các quan sát của bộ dữ liệu:

case_table %>% 
  str_glue_data("{zone}: {new_cases} ({total_cases} total cases)")
## Zone 1: 3 (40 total cases)
## Zone 2: 0 (4 total cases)
## Zone 3: 7 (25 total cases)
## Zone 4: 0 (10 total cases)
## Zone 5: 15 (103 total cases)

Kết hợp các chuỗi ký tự trên các dòng

Nếu bạn đang cố gắng để “gộp” các giá trị trong một cột của bộ dữ liệu, ví dụ: kết hợp các giá trị từ nhiều hàng thành một hàng bằng cách gắn chúng với nhau cùng ký tự phân cách, hãy xem thêm ở chương Loại bỏ trùng lặp mục “gộp” các giá trị.

Một bộ dữ liệu thành một dòng

Bạn có thể tạo ra dãy thông tin chỉ trong một dòng bằng cách sử dụng lệnh str_c() (cụ thể tên bộ dữ liệu và tên cột), đồng thời cung cấp các đối số sep =collapse =.

str_c(case_table$zone, case_table$new_cases, sep = " = ", collapse = ";  ")
## [1] "Zone 1 = 3;  Zone 2 = 0;  Zone 3 = 7;  Zone 4 = 0;  Zone 5 = 15"

Bạn có thể thêm đoạn tiền tố “New Cases:” vào đầu dòng thông tin bằng cách đặt trong hàm str_c() (nếu “New Cases:” nằm trong hàm str_c() ban đầu thì nó sẽ xuất hiện nhiều lần).

str_c("New Cases: ", str_c(case_table$zone, case_table$new_cases, sep = " = ", collapse = ";  "))
## [1] "New Cases: Zone 1 = 3;  Zone 2 = 0;  Zone 3 = 7;  Zone 4 = 0;  Zone 5 = 15"

Hợp nhất các cột

Trong bộ dữ liệu, việc tập hợp các giá trị dạng ký tự từ nhiều cột lại với nhau có thể thực hiện bằng cách dùng hàm unite() từ package tidyr. Tính năng này ngược lại với hàm separate().

Đầu tiên, cần tên của cột mới. Sau đó, cần tên của các cột mà bạn muốn hợp nhất.

  • Mặc định, dấu ngăn cách được sử dụng trong cột hợp nhất là dấu gạch dưới _, nhưng có thể được thay đổi bằng đối số sep =.
  • remove = loại bỏ các cột ban đầu ra khỏi bộ dữ liệu (mặc định là TRUE)
  • na.rm = loại bỏ các giá trị bị thiếu trong khi hợp nhất (mặc định là FALSE)

Dưới đây, chúng tôi xác định một bộ dữ liệu ngắn để minh họa:

df <- data.frame(
  case_ID = c(1:6),
  symptoms  = c("jaundice, fever, chills",     # patient 1
                "chills, aches, pains",        # patient 2 
                "fever",                       # patient 3
                "vomiting, diarrhoea",         # patient 4
                "bleeding from gums, fever",   # patient 5
                "rapid pulse, headache"),      # patient 6
  outcome = c("Recover", "Death", "Death", "Recover", "Recover", "Recover"))
df_split <- separate(df, symptoms, into = c("sym_1", "sym_2", "sym_3"), extra = "merge")
## Warning: Expected 3 pieces. Missing pieces filled with `NA` in 2 rows [3, 4].

Đây là bộ dữ liệu mẫu:

Dưới đây, chúng tôi hợp nhất ba cột triệu chứng:

df_split %>% 
  unite(
    col = "all_symptoms",         # name of the new united column
    c("sym_1", "sym_2", "sym_3"), # columns to unite
    sep = ", ",                   # separator to use in united column
    remove = TRUE,                # if TRUE, removes input cols from the data frame
    na.rm = TRUE                  # if TRUE, missing values are removed before uniting
  )
##   case_ID                all_symptoms outcome
## 1       1     jaundice, fever, chills Recover
## 2       2        chills, aches, pains   Death
## 3       3                       fever   Death
## 4       4         vomiting, diarrhoea Recover
## 5       5 bleeding, from, gums, fever Recover
## 6       6      rapid, pulse, headache Recover

Tách chuỗi

Để tách một chuỗi ký tự dựa trên một quy luật, hãy sử dụng hàm str_split(). Hàm này đánh giá (các) chuỗi ký tự và trả về danh sách list các vectơ ký tự chứa các giá trị mới được tách.

Ví dụ đơn giản dưới đây đánh giá một chuỗi ký tự và chia nó thành ba phần. Mặc định, hàm trả về một đối tượng kiểu danh sách list với một phần tử (một vectơ ký tự) cho mỗi chuỗi được cung cấp ban đầu. Nếu simplify = TRUE nó trả về một ma trận ký tự.

Trong ví dụ này, một chuỗi ký tự được cung cấp và hàm trả về một danh sách có một phần tử - một vectơ ký tự chứa ba giá trị.

str_split(string = "jaundice, fever, chills",
          pattern = ",")
## [[1]]
## [1] "jaundice" " fever"   " chills"

Nếu kết quả được lưu, thì bạn có thể truy cập giá trị phân chia thứ n bằng cú pháp dấu ngoặc vuông. Để truy cập vào một giá trị cụ thể, bạn có thể sử dụng cú pháp như sau: the_returned_object[[1]][2], sẽ truy cập giá trị thứ hai từ chuỗi ký tự được đánh giá thứ nhất (“fever”). Xem thêm ở chương R Cơ bản để biết thêm chi tiết về cách truy vấn các phần tử.

pt1_symptoms <- str_split("jaundice, fever, chills", ",")

pt1_symptoms[[1]][2]  # extracts 2nd value from 1st (and only) element of the list
## [1] " fever"

Nếu nhiều chuỗi ký tự được sử dụng trong hàm str_split(), sẽ có nhiều hơn một phần tử trong danh sách trả về.

symptoms <- c("jaundice, fever, chills",     # patient 1
              "chills, aches, pains",        # patient 2 
              "fever",                       # patient 3
              "vomiting, diarrhoea",         # patient 4
              "bleeding from gums, fever",   # patient 5
              "rapid pulse, headache")       # patient 6

str_split(symptoms, ",")                     # split each patient's symptoms
## [[1]]
## [1] "jaundice" " fever"   " chills" 
## 
## [[2]]
## [1] "chills" " aches" " pains"
## 
## [[3]]
## [1] "fever"
## 
## [[4]]
## [1] "vomiting"   " diarrhoea"
## 
## [[5]]
## [1] "bleeding from gums" " fever"            
## 
## [[6]]
## [1] "rapid pulse" " headache"

Thay vào đó, để trả về “ma trận chuỗi ký tự”, có thể sẽ hữu ích nếu tạo cột trong bộ dữ liệu, đặt đối số simplify = TRUE như trình bày dưới đây:

str_split(symptoms, ",", simplify = TRUE)
##      [,1]                 [,2]         [,3]     
## [1,] "jaundice"           " fever"     " chills"
## [2,] "chills"             " aches"     " pains" 
## [3,] "fever"              ""           ""       
## [4,] "vomiting"           " diarrhoea" ""       
## [5,] "bleeding from gums" " fever"     ""       
## [6,] "rapid pulse"        " headache"  ""

Bạn cũng có thể điều chỉnh số phần tách ra với đối số n =. Ví dụ dưới đây giới hạn số phần tách ra là 2. Bất kỳ dấu phẩy nào khác vẫn sẽ nằm trong giá trị thứ hai.

str_split(symptoms, ",", simplify = TRUE, n = 2)
##      [,1]                 [,2]            
## [1,] "jaundice"           " fever, chills"
## [2,] "chills"             " aches, pains" 
## [3,] "fever"              ""              
## [4,] "vomiting"           " diarrhoea"    
## [5,] "bleeding from gums" " fever"        
## [6,] "rapid pulse"        " headache"

Lưu ý - các kết quả tương tự có thể đạt được với hàm str_split_fixed(), trong đó bạn không dùng đối số simplify mà thay vào đó phải chỉ định số cột (n).

str_split_fixed(symptoms, ",", n = 2)

Tách cột

Nếu bạn đang cố gắng chia tách cột trong bộ dữ liệu, cách tốt nhất là sử dụng hàm separate() từ package dplyr. Nó được sử dụng để chia một cột ký tự thành các cột khác nhau.

Giả sử chúng ta có một bộ dữ liệu đơn giản df (được xác định và hợp nhất trong unite section) chứa một cột case_ID , một cột dạng ký tự có nhiều triệu chứng và một cột outcome. Mục tiêu của chúng ta là tách cột symptoms thành nhiều cột - mỗi cột chứa một triệu chứng.

Giả sử dữ liệu được đưa vào hàm separate(), trước tiên hãy chọn ra cột sẽ được phân tách. Sau đó, cung cấp thông tin tới đối số into = dưới dạng vectơ c( ) có chứa tên các cột mới, như được trình bày dưới đây.

  • Dấu phân cách trong sep = có thể là một ký tự hoặc một số (được hiểu là vị trí ký tự cần tách)

  • Mặc định là remove = FALSE, xóa cột đầu vào ban ban đầu

  • Mặc định là convert = FALSE, các ký tự “NA” sẽ thành NA

  • extra = kiểm soát điều gì sẽ xảy ra nếu có nhiều giá trị được tạo bởi sự phân tách nhiều hơn các cột mới được đặt tên.

    • extra = "warn" có nghĩa là bạn sẽ thấy một cảnh báo nhưng nó sẽ loại bỏ các giá trị thừa (mặc định là vậy)
    • extra = "drop" có nghĩa là các giá trị thừa sẽ bị loại bỏ mà không có cảnh báo
    • extra = "merge" sẽ chỉ phân tách thành số cột mới được liệt kê trong into - thiết lập này sẽ bảo toàn tất cả dữ liệu của bạn

Dưới đây là một ví dụ về extra = "merge" - không có dữ liệu nào bị mất. Hai cột mới được xác định nhưng bất kỳ triệu chứng thứ ba nào sẽ quy về trong cột mới thứ hai:

# third symptoms combined into second new column
df %>% 
  separate(symptoms, into = c("sym_1", "sym_2"), sep=",", extra = "merge")
## Warning: Expected 2 pieces. Missing pieces filled with `NA` in 1 rows [3].
##   case_ID              sym_1          sym_2 outcome
## 1       1           jaundice  fever, chills Recover
## 2       2             chills   aches, pains   Death
## 3       3              fever           <NA>   Death
## 4       4           vomiting      diarrhoea Recover
## 5       5 bleeding from gums          fever Recover
## 6       6        rapid pulse       headache Recover

Khi sử dụng lệnh extra = "drop" mặc định như bên dưới, một cảnh báo sẽ được đưa ra nhưng triệu chứng thứ ba bị mất:

# third symptoms are lost
df %>% 
  separate(symptoms, into = c("sym_1", "sym_2"), sep=",")
## Warning: Expected 2 pieces. Additional pieces discarded in 2 rows [1, 2].
## Warning: Expected 2 pieces. Missing pieces filled with `NA` in 1 rows [3].
##   case_ID              sym_1      sym_2 outcome
## 1       1           jaundice      fever Recover
## 2       2             chills      aches   Death
## 3       3              fever       <NA>   Death
## 4       4           vomiting  diarrhoea Recover
## 5       5 bleeding from gums      fever Recover
## 6       6        rapid pulse   headache Recover

CẨN TRỌNG: Nếu bạn không cung cấp đủ giá trị into cho các cột mới, dữ liệu của bạn có thể bị cắt bớt .

Sắp xếp theo thứ tự bảng chữ cái

Một số chuỗi ký tự có thể được sắp xếp theo thứ tự bảng chữ cái. Hàm str_order() trả về thứ tự của các phần tử, trong khi hàm str_sort() trả về các chuỗi theo thứ tự đó.

# strings
health_zones <- c("Alba", "Takota", "Delta")

# return the alphabetical order
str_order(health_zones)
## [1] 1 3 2
# return the strings in alphabetical order
str_sort(health_zones)
## [1] "Alba"   "Delta"  "Takota"

Để sử dụng một bảng chữ cái khác, hãy thêm đối số locale =. Xem danh sách đầy đủ các locales bằng cách gõ stringi::stri_locale_list() trong cửa sổ R console.

Các hàm base R

Các hàm phổ biến của base R là paste()paste0() nối các vectơ sau khi chuyển đổi tất cả các cấu phần thành ký tự. Chúng hoạt động tương tự như str_c() nhưng cú pháp được cho là phức tạp hơn - đó là trong ngoặc thì mỗi phần được phân tách bằng một dấu phẩy. Các cấu phần là ký tự dạng văn bản (trong dấu ngoặc kép) hoặc các đối tượng được xác định trước (không có dấu ngoặc kép). Ví dụ:

n_beds <- 10
n_masks <- 20

paste0("Regional hospital needs ", n_beds, " beds and ", n_masks, " masks.")
## [1] "Regional hospital needs 10 beds and 20 masks."

Đối số sep =collapse = có thể được cụ thể. Hàm paste() chỉ đơn giản dán paste0() vớ đối số mặc định sep = " " (một khoảng trắng).

10.3 Làm sạch và chuẩn hóa

Thay đổi chữ hoa/chữ thường

Thông thường thì người ta cần phải thay đổi cách viết thường/viết hoa của một giá trị dạng chuỗi ký tự, ví dụ như tên địa danh. Hãy sử dụng hàm str_to_upper(), str_to_lower(), và str_to_title() từ stringr, như dưới đây:

str_to_upper("California")
## [1] "CALIFORNIA"
str_to_lower("California")
## [1] "california"

Sử dụng base R, bạn cũng có thể thực hiện điều trên với hàm toupper(), tolower().

Định dạng tiêu đề

Biến đổi chuỗi ký tự sao cho mỗi từ được viết hoa có thể thực hiện được với hàm str_to_title():

str_to_title("go to the US state of california ")
## [1] "Go To The Us State Of California "

Sử dụng hàm toTitleCase() từ package tools để chuyển đổi nhiều kiểu viết in hoa hơn (các từ như “to”, “the” và “of” không cần viết hoa).

tools::toTitleCase("This is the US state of california")
## [1] "This is the US State of California"

Bạn cũng có thể sử dụng hàm str_to_sentence(), chỉ viết hoa chữ cái đầu tiên của chuỗi ký tự.

str_to_sentence("the patient must be transported")
## [1] "The patient must be transported"

Độ dài chuỗi ký tự

Sử dụng hàm str_pad() để thêm các ký tự vào một chuỗi, với độ dài tối thiểu. Mặc định, khoảng trắng sẽ được thêm vào, nhưng bạn cũng có thể chèn các ký tự khác bằng cách sử dụng đối số pad =.

# ICD codes of differing length
ICD_codes <- c("R10.13",
               "R10.819",
               "R17")

# ICD codes padded to 7 characters on the right side
str_pad(ICD_codes, 7, "right")
## [1] "R10.13 " "R10.819" "R17    "
# Pad with periods instead of spaces
str_pad(ICD_codes, 7, "right", pad = ".")
## [1] "R10.13." "R10.819" "R17...."

Ví dụ: để chèn thêm số bằng các số 0 ở đầu (chẳng hạn như giờ hoặc phút), bạn có thể chèn số có độ dài tối thiểu là 2 với pad = "0".

# Add leading zeros to two digits (e.g. for times minutes/hours)
str_pad("4", 2, pad = "0") 
## [1] "04"
# example using a numeric column named "hours"
# hours <- str_pad(hours, 2, pad = "0")

Cắt chuỗi ký tự

Hàm str_trunc() thiết lập độ dài tối đa cho mỗi chuỗi ký tự. Nếu một chuỗi vượt quá độ dài này, nó sẽ bị xén (rút ngắn) và kết thúc bằng một dấu ba chấm (…) ám chỉ rằng chuỗi đó chưa hiển thị hết các ký tự. Lưu ý rằng dấu ba chấm được tính toán phụ thuộc vào độ dài. Các ký tự dấu ba chấm có thể được thay đổi bằng đối số ellipsis =. Đối số tùy chọn side = làm rõ vị trí mà dấu ba chấm sẽ xuất hiện trong chuỗi bị cắt ngắn (bên “trái”, “phải” hoặc “giữa”).

original <- "Symptom onset on 4/3/2020 with vomiting"
str_trunc(original, 10, "center")
## [1] "Symp...ing"

Chuẩn hóa độ dài

Sử dụng hàm str_trunc() để thiết lập độ dài tối đa, sau đó sử dụng hàm str_pad() để tăng thêm độ dài cho các chuỗi rất ngắn sao cho bằng độ dài tiêu chuẩn. Trong ví dụ dưới đây, độ dài tối đa là 6 (một ký tự bị cắt giảm), và sau đó một giá trị rất ngắn được đệm thêm để đạt được độ dài chuỗi là 6.

# ICD codes of differing length
ICD_codes   <- c("R10.13",
                 "R10.819",
                 "R17")

# truncate to maximum length of 6
ICD_codes_2 <- str_trunc(ICD_codes, 6)
ICD_codes_2
## [1] "R10.13" "R10..." "R17"
# expand to minimum length of 6
ICD_codes_3 <- str_pad(ICD_codes_2, 6, "right")
ICD_codes_3
## [1] "R10.13" "R10..." "R17   "

Xóa khoảng trắng đầu/cuối

Sử dụng hàm str_trim() để xóa khoảng trắng, dòng mới (\n) hoặc tabs (\t) ở các phía của chuỗi đầu vào. Thêm "right" "left", hoặc "both" vào lệnh để xác định phía nào cần cắt (ví dụ: str_trim(x, "right").

# ID numbers with excess spaces on right
IDs <- c("provA_1852  ", # two excess spaces
         "provA_2345",   # zero excess spaces
         "provA_9460 ")  # one excess space

# IDs trimmed to remove excess spaces on right side only
str_trim(IDs)
## [1] "provA_1852" "provA_2345" "provA_9460"

Xóa khoảng trắng lặp lại phía trong

Sử dụng hàm str_squish() để loại bỏ các khoảng trắng lặp lại bên trong một chuỗi. Ví dụ, để chuyển đổi khoảng trắng lặp thành khoảng trắng đơn. Điều này cũng sẽ loại bỏ dấu cách, dòng mới hoặc tab ở phía bên ngoài chuỗi như giống như hàm str_trim().

# original contains excess spaces within string
str_squish("  Pt requires   IV saline\n") 
## [1] "Pt requires IV saline"

?str_trim, ?str_pad vào cửa sổ R console để biết thêm chi tiết.

Gói lại thành đoạn văn bản

Sử dụng hàm str_wrap() để gói một đoạn văn bản dài không có cấu trúc thành một đoạn văn có cấu trúc với độ dài các dòng là cố định. Cần xác định độ dài lý tưởng cho mỗi dòng và áp dụng một thuật toán để chèn thêm dòng mới (\n) vào trong đoạn văn bản, như ví dụ bên dưới.

pt_course <- "Symptom onset 1/4/2020 vomiting chills fever. Pt saw traditional healer in home village on 2/4/2020. On 5/4/2020 pt symptoms worsened and was admitted to Lumta clinic. Sample was taken and pt was transported to regional hospital on 6/4/2020. Pt died at regional hospital on 7/4/2020."

str_wrap(pt_course, 40)
## [1] "Symptom onset 1/4/2020 vomiting chills\nfever. Pt saw traditional healer in\nhome village on 2/4/2020. On 5/4/2020\npt symptoms worsened and was admitted\nto Lumta clinic. Sample was taken and pt\nwas transported to regional hospital on\n6/4/2020. Pt died at regional hospital\non 7/4/2020."

Hàm cat() trong base R có thể xử lý toàn bộ câu lệnh trên để trả kết quả, hiển thị các dòng mới được thêm vào.

cat(str_wrap(pt_course, 40))
## Symptom onset 1/4/2020 vomiting chills
## fever. Pt saw traditional healer in
## home village on 2/4/2020. On 5/4/2020
## pt symptoms worsened and was admitted
## to Lumta clinic. Sample was taken and pt
## was transported to regional hospital on
## 6/4/2020. Pt died at regional hospital
## on 7/4/2020.

10.4 Xử lý theo vị trí

Tách chuỗi theo vị trí ký tự

Sử dụng hàm str_sub() để trả về một phần của chuỗi. Hàm chứa 3 đối số chính là:

  1. các vector ký tự
  2. vị trí bắt đầu
  3. vị trí kết thúc

Một vài lưu ý về số thứ tự vị trí:

  • Nếu số thứ tự vị trí là số dương, vị trí được xử lý bắt đầu từ vị trí cuối cùng bên trái của chuỗi.
  • Nếu số thứ tự vị trí là số âm, vị trí được xử lý bắt đầu từ vị trí cuối cùng bên phải của chuỗi.
  • Số thứ tự vị trí được bao gồm.
  • Các vị trí vượt quá chuỗi sẽ bị cắt bớt (loại bỏ).

Dưới đây là một số ví dụ được áp dụng cho chuỗi ký tự “pneumonia”:

# start and end third from left (3rd letter from left)
str_sub("pneumonia", 3, 3)
## [1] "e"
# 0 is not present
str_sub("pneumonia", 0, 0)
## [1] ""
# 6th from left, to the 1st from right
str_sub("pneumonia", 6, -1)
## [1] "onia"
# 5th from right, to the 2nd from right
str_sub("pneumonia", -5, -2)
## [1] "moni"
# 4th from left to a position outside the string
str_sub("pneumonia", 4, 15)
## [1] "umonia"

Tách theo vị trí từ

Để tách ‘từ’ thứ n, hãy sử dụng hàm word() cũng thuộc package stringr. Đầu tiên, xác định (các) chuỗi ký tự, sau đó là vị trí từ đầu tiên cần trích xuất và vị trí từ cuối cùng để trích xuất.

Mặc định, dấu phân cách giữa các ‘từ’ được giả định là khoảng trắng, trừ khi được chỉ định cách khác bằng đối số sep = (ví dụ: sep = "_" khi các từ được phân tách bằng dấu gạch dưới)

# strings to evaluate
chief_complaints <- c("I just got out of the hospital 2 days ago, but still can barely breathe.",
                      "My stomach hurts",
                      "Severe ear pain")

# extract 1st to 3rd words of each string
word(chief_complaints, start = 1, end = 3, sep = " ")
## [1] "I just got"       "My stomach hurts" "Severe ear pain"

Thay thế theo vị trí ký tự

Hàm str_sub() được ghép nối với toán tử gán (<-) có thể được sử dụng để sửa đổi một phần của chuỗi ký tự:

word <- "pneumonia"

# convert the third and fourth characters to X 
str_sub(word, 3, 4) <- "XX"

# print
word
## [1] "pnXXmonia"

Một ví dụ áp dụng cho nhiều chuỗi (ví dụ: một cột). Lưu ý sự mở rộng về độ dài của từ “HIV”.

words <- c("pneumonia", "tubercolosis", "HIV")

# convert the third and fourth characters to X 
str_sub(words, 3, 4) <- "XX"

words
## [1] "pnXXmonia"    "tuXXrcolosis" "HIXX"

Đánh giá độ dài chuỗi

str_length("abc")
## [1] 3

Ngoài ra, có thể sử dụng hàm nchar() từ base R

10.5 Quy luật chuỗi

Nhiều hàm stringr được sử dụng để nhận diện, định vị, trích xuất, khớp, thay thế và phân tách dựa trên một pattern - quy luật được chỉ định. .

Nhận diện quy luật

Sử dụng hàm str_detect() như bên dưới để phát hiện sự hiện diện/sự vắng mặt của một quy luật trong chuỗi. Đầu tiên, hãy cung cấp cho chuỗi hoặc vectơ cần tìm tới hàm (string =), sau đó là quy luật tìm kiếm (pattern =). Lưu ý rằng theo mặc định thì tìm kiếm phân biệt chữ hoa chữ thường!

str_detect(string = "primary school teacher", pattern = "teach")
## [1] TRUE

Đối số negate = có thể được bao gồm và đặt thành TRUE nếu bạn muốn tìm một quy luật KHÔNG xuất hiện.

str_detect(string = "primary school teacher", pattern = "teach", negate = TRUE)
## [1] FALSE

Để bỏ qua chữ hoa / chữ thường, hãy đặt pattern trong hàm regex(), và bên trong hàm regex() hãy thêm đối số ignore_case = TRUE (hoặc viết tắt là T).

str_detect(string = "Teacher", pattern = regex("teach", ignore_case = T))
## [1] TRUE

Khi hàm str_detect() được áp dụng cho một vectơ ký tự hoặc một cột trong bộ dữ liệu, nó sẽ trả về giá trị TRUE hoặc FALSE cho mỗi giá trị.

# a vector/column of occupations 
occupations <- c("field laborer",
                 "university professor",
                 "primary school teacher & tutor",
                 "tutor",
                 "nurse at regional hospital",
                 "lineworker at Amberdeen Fish Factory",
                 "physican",
                 "cardiologist",
                 "office worker",
                 "food service")

# Detect presence of pattern "teach" in each string - output is vector of TRUE/FALSE
str_detect(occupations, "teach")
##  [1] FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Nếu bạn cần đếm giá trị TRUE, chỉ cần đơn giản tính tổng bằng hàm sum() kết quả đầu ra. Nó sẽ đếm số lượng giá trị TRUE.

sum(str_detect(occupations, "teach"))
## [1] 1

Để tìm kiếm bao gồm nhiều cụm từ, hãy nhóm chúng bằng ký tự OR (|) bên trong đối số pattern = như được trình bày dưới đây:

sum(str_detect(string = occupations, pattern = "teach|professor|tutor"))
## [1] 3

Nếu bạn cần xây dựng một danh sách dài gồm các cụm từ cần tìm kiếm, bạn có thể kết hợp chúng bằng cách sử dụng hàm str_c()sep = |, sau đó chỉ định nó là một đối tượng dạng ký tự, và sau đó tham chiếu vector một cách ngắn gọn hơn. Ví dụ dưới đây bao gồm các cụm từ tìm kiếm bao gồm các nghề nghiệp có thể sử dụng cho các nhà cung cấp dịch vụ y tế tuyến đầu.

# search terms
occupation_med_frontline <- str_c("medical", "medicine", "hcw", "healthcare", "home care", "home health",
                                "surgeon", "doctor", "doc", "physician", "surgery", "peds", "pediatrician",
                               "intensivist", "cardiologist", "coroner", "nurse", "nursing", "rn", "lpn",
                               "cna", "pa", "physician assistant", "mental health",
                               "emergency department technician", "resp therapist", "respiratory",
                                "phlebotomist", "pharmacy", "pharmacist", "hospital", "snf", "rehabilitation",
                               "rehab", "activity", "elderly", "subacute", "sub acute",
                                "clinic", "post acute", "therapist", "extended care",
                                "dental", "dential", "dentist", sep = "|")

occupation_med_frontline
## [1] "medical|medicine|hcw|healthcare|home care|home health|surgeon|doctor|doc|physician|surgery|peds|pediatrician|intensivist|cardiologist|coroner|nurse|nursing|rn|lpn|cna|pa|physician assistant|mental health|emergency department technician|resp therapist|respiratory|phlebotomist|pharmacy|pharmacist|hospital|snf|rehabilitation|rehab|activity|elderly|subacute|sub acute|clinic|post acute|therapist|extended care|dental|dential|dentist"

Lệnh này trả về số lượng nghề nghiệp mà chứa bất kỳ một trong các cụm từ tìm kiếm dành cho nhà cung cấp dịch vụ y tế tuyến đầu (occupation_med_frontline):

sum(str_detect(string = occupations, pattern = occupation_med_frontline))
## [1] 2

Các hàm tìm kiếm chuỗi trong Base R

Hàm grepl() trong base R hoạt động tương tự như hàm str_detect(), trong đó nó tìm kiếm các kết quả phù hợp với một quy luật và trả về một vectơ logic. Cú pháp cơ bản đó là grepl(pattern, strings_to_search, ignore.case = FALSE, ...). Một ưu điểm đó là đối số ignore.case dễ viết hơn (không cần có sự tham gia của hàm regex()).

Tương tự như vậy, các hàm sub()gsub() của base R hoạt động tương tự như hàm str_replace(). Cú pháp cơ bản đó là: gsub(pattern, replacement, strings_to_search, ignore.case = FALSE). sub() sẽ thay thế trường hợp đầu tiên của pattern, trong khi gsub() sẽ thay thế tất cả các trường hợp của pattern.

Chuyển đổi dấu phẩy thành dấu chấm

Sau đây là một ví dụ về việc sử dụng hàm gsub() để chuyển đổi dấu phẩy thành dấu chấm trong một vectơ dạng số. Điều này có thể hữu ích nếu dữ liệu của bạn bắt nguồn từ nhiều nơi trên thế giới ngoài Hoa Kỳ hoặc Vương quốc Anh.

Hàm gsub() ở bên trong đầu tiên hoạt động trên đối tượng lengths để chuyển đổi bất kỳ dấu chấm nào thành không có khoảng trắng "“. Ký tự dấu chấm”." phải được “đi liền” với hai dấu gạch chéo để biểu thị một dấu chấm, bởi vì “.” trong biểu thức chính quy có nghĩa là “bất kỳ ký tự nào”. Sau đó, kết quả (chỉ có dấu phẩy) được chuyển tiếp đến hàm gsub() bên ngoài trong đó dấu phẩy được thay thế bằng dấu chấm.

lengths <- c("2.454,56", "1,2", "6.096,5")

as.numeric(gsub(pattern = ",",                # find commas     
                replacement = ".",            # replace with periods
                x = gsub("\\.", "", lengths)  # vector with other periods removed (periods escaped)
                )
           )                                  # convert outcome to numeric

Thay thế toàn bộ

Sử dụng hàm str_replace_all() như là một công cụ “find and replace (tìm kiếm và thay thế)”. Đầu tiên, cung cấp các chuỗi ký tự sẽ được đánh giá tới đối số string =, sau đó là quy luật sẽ được thay thế vào đối số pattern =, và sau đó là giá trị thay thế vào replacement =. Ví dụ dưới đây thay thế tất cả các trường hợp “dead” bằng “deceased”. Lưu ý, phân biệt chữ hoa chữ thường.

outcome <- c("Karl: dead",
            "Samantha: dead",
            "Marco: not dead")

str_replace_all(string = outcome, pattern = "dead", replacement = "deceased")
## [1] "Karl: deceased"      "Samantha: deceased"  "Marco: not deceased"

Lưu ý:

  • Để thay thế một pattern cho NA, sử dụng hàm str_replace_na().
  • Hàm str_replace() thay thế duy nhất trường hợp đầu tiên của pattern trong mỗi chuỗi ký tự.

Nhận diện logic

Bên trong hàm case_when()

str_detect() thường được sử dụng trong hàm case_when() (từ dplyr). Hãy coi occupations là một cột trong bộ linelist. Hàm mutate() dưới đây tạo một cột mới gọi là is_educator bằng cách sử dụng logic có điều kiện bởi case_when(). Xem thêm ở chương về làm sạch dữ liệu để hiểu hơn về hàm case_when().

df <- df %>% 
  mutate(is_educator = case_when(
    # term search within occupation, not case sensitive
    str_detect(occupations,
               regex("teach|prof|tutor|university",
                     ignore_case = TRUE))              ~ "Educator",
    # all others
    TRUE                                               ~ "Not an educator"))

Xin nhắc lại, điều quan trọng là phải thêm tiêu chí loại trừ vào điều kiện logic (negate = F):

df <- df %>% 
  # value in new column is_educator is based on conditional logic
  mutate(is_educator = case_when(
    
    # occupation column must meet 2 criteria to be assigned "Educator":
    # it must have a search term AND NOT any exclusion term
    
    # Must have a search term
    str_detect(occupations,
               regex("teach|prof|tutor|university", ignore_case = T)) &              
    
    # AND must NOT have an exclusion term
    str_detect(occupations,
               regex("admin", ignore_case = T),
               negate = TRUE                        ~ "Educator"
    
    # All rows not meeting above criteria
    TRUE                                            ~ "Not an educator"))

Định vị vị trí pattern

Để xác định vị trí đầu tiên của một pattern, hãy sử dụng hàm str_locate(). Nó xuất ra vị trí bắt đầu và kết thúc.

str_locate("I wish", "sh")
##      start end
## [1,]     5   6

Giống như các hàm str khác, có một phiên bản “_all” (str_locate_all()) sẽ trả về vị trí của tất cả các phiên bản của pattern trong mỗi chuỗi. Kết quả này xuất ra dưới dạng danh sách list.

phrases <- c("I wish", "I hope", "he hopes", "He hopes")

str_locate(phrases, "h" )     # position of *first* instance of the pattern
##      start end
## [1,]     6   6
## [2,]     3   3
## [3,]     1   1
## [4,]     4   4
str_locate_all(phrases, "h" ) # position of *every* instance of the pattern
## [[1]]
##      start end
## [1,]     6   6
## 
## [[2]]
##      start end
## [1,]     3   3
## 
## [[3]]
##      start end
## [1,]     1   1
## [2,]     4   4
## 
## [[4]]
##      start end
## [1,]     4   4

Trích xuất kết quả ghép cặp

str_extract_all() trả về các patterns được matching, sẽ hữu dụng nhất khi bạn cung cấp một vài patterns thông qua điều kiện “OR”. Ví dụ: tìm trong vectơ chuỗi nghề nghiệp (xem tab trước) các từ “teach”, “prof” hoặc “tutor”.

str_extract_all() trả về một danh sách list chứa tất cả các kết quả ghép cặp cho mỗi chuỗi được đánh giá. Xem dưới đây ta thấy occupation 3 có hai pattern được tìm thấy.

str_extract_all(occupations, "teach|prof|tutor")
## [[1]]
## character(0)
## 
## [[2]]
## [1] "prof"
## 
## [[3]]
## [1] "teach" "tutor"
## 
## [[4]]
## [1] "tutor"
## 
## [[5]]
## character(0)
## 
## [[6]]
## character(0)
## 
## [[7]]
## character(0)
## 
## [[8]]
## character(0)
## 
## [[9]]
## character(0)
## 
## [[10]]
## character(0)

str_extract() chỉ trích xuất kết quả ghép cặp đầu tiên trong mỗi chuỗi được xem xét, tạo ra một vectơ ký tự với một phần tử cho mỗi chuỗi được xem xét. Nó trả về giá trị NA khi không có giá trị nào được tìm thấy. Các giá trị NA có thể được loại bỏ bằng cách đặt vectơ trả về trong hàm na.exclude(). Lưu ý đoạn khớp nối thứ hai của occupation 3 không được hiển thị.

str_extract(occupations, "teach|prof|tutor")
##  [1] NA      "prof"  "teach" "tutor" NA      NA      NA      NA      NA      NA

Tập hợp con và số lượng

Bao gồm hàm str_subset()str_count().

str_subset() trả về các giá trị thực có chứa pattern:

str_subset(occupations, "teach|prof|tutor")
## [1] "university professor"           "primary school teacher & tutor" "tutor"

str_count() trả về một vectơ số: số lần một cụm từ tìm kiếm xuất hiện trong mỗi giá trị được xem xét.

str_count(occupations, regex("teach|prof|tutor", ignore_case = TRUE))
##  [1] 0 1 2 1 0 0 0 0 0 0

Nhóm Regex

ĐANG ĐƯỢC XÂY DỰNG

10.6 Các ký tự đặc biệt

Dấu gạch chéo ngược \ để bỏ qua

Dấu gạch chéo ngược \ được sử dụng “để bỏ qua” nghĩa của ký tự tiếp theo. Bằng cách này, dấu gạch chéo ngược có thể được sử dụng để hiển thị dấu ngoặc kép bên trong các dấu ngoặc kép khác (\") - dấu ngoặc kép ở giữa sẽ không “phá vỡ” các dấu ngoặc kép xung quanh.

Lưu ý - do đó, nếu bạn muốn hiển thị một dấu gạch chéo ngược, bạn phải ngắt nghĩa của nó bằng một dấu gạch chéo ngược khác. Vì vậy, bạn phải viết hai dấu gạch chéo ngược \\ để chỉ hiển thị một.

Các ký tự đặc biệt

Ký tự đặc biệt Ý nghĩa
"\\" Dấu gạch chéo ngược
"\n" một dòng mới
"\"" dấu ngoặc kép trong dấu ngoặc kép
'\'' dấu ngoặc đơn trong dấu ngoặc đơn
"\| grave accent| carriage return| tab| vertical tab"` backspace

?"'" trong cửa sổ R Console để hiển thị danh sách đầy đủ các ký tự đặc biệt (nó sẽ xuất hiện trong cửa sổ Help của RStudio).

10.7 Biểu thức chính quy (regex)

10.8 Regex và các ký tự đặc biệt

Biểu thức chính quy, hoặc “regex”, là một ngôn ngữ ngắn gọn để mô tả các patterns trong chuỗi ký tự. Nếu bạn không quen với nó, một biểu thức chính quy có thể trông giống như một ngôn ngữ ngoài hành tinh. Ở đây chúng tôi cố lột tả ngôn ngữ này dễ hiểu hơn

Phần lớn nội dung mục này được tham khảo từ hướng dẫn nàycheatsheet này. Chúng tôi tóm tắt một cách chọn lọc ở đây khi biết rằng cuốn ebook này có thể được xem bởi những người không có quyền truy cập internet để có thể xem các hướng dẫn khác.

Một biểu thức chính quy thường được áp dụng để trích xuất các pattern cụ thể từ văn bản “không có cấu trúc” - ví dụ: ghi chú y tế, khiếu nại, tiền sử bệnh tật hoặc các cột văn bản khác trong bộ dữ liệu.

Có bốn công cụ cơ bản mà người ta có thể sử dụng để tạo một biểu thức chính quy cơ bản:

  1. Bộ ký tự
  2. Siêu ký tự
  3. Bộ định lượng
  4. Nhóm

Bộ ký tự

Bộ ký tự, là một cách thể hiện các tùy chọn liệt kê phù hợp với ký tự gốc, trong dấu ngoặc. Vì vậy, mọi kết quả khớp sẽ được đánh dấu nếu tìm thấy bất kỳ ký tự nào trong dấu ngoặc trong chuỗi. Ví dụ, để tìm các nguyên âm, người ta có thể sử dụng bộ ký tự này: “[aeiou]”. Một số bộ ký tự phổ biến khác là:

Bộ ký tự Ghép cặp
"[A-Z]" bất kỳ ký tự viết hoa đơn lẻ nào
"[a-z]" bất kỳ ký tự viết thường đơn lẻ nào
"[0-9]" bất kỳ số nào
[:alnum:] bất kỳ ký tự chữ và số nào
[:digit:] bất kỳ chữ số nào
[:alpha:] bất kỳ ký tự nào (viết hoa hoặc viết thường)
[:upper:] bất kỳ ký tự viết hoa nào
[:lower:] bất kỳ ký tự viết thường nào

Các bộ ký tự có thể được kết hợp trong một dấu ngoặc vuông (không có khoảng trắng!), chẳng hạn như "[A-Za-z]" (bất kỳ chữ cái viết hoa hoặc viết thường nào), hoặc một ví dụ khác "[t-z0-5]" (từ t viết thường đến z HOẶC số 0 đến 5).

Siêu ký tự

Các siêu ký tự là cách viết tắt của các bộ ký tự. Một số điều quan trọng được liệt kê dưới đây:

Siêu ký tự Ý nghĩa
"\\s" khoảng trắng đơn
"\\w" bất kỳ ký tự chữ hoặc số đơn lẻ nào (A-Z, a-z, or 0-9)
"\\d" bất kỳ chữ số đơn lẻ nào (0-9)

Bộ định lượng

Thông thường, bạn không muốn tìm kiếm kết quả phù hợp chỉ trên một ký tự. Bộ định lượng cho phép bạn chỉ định độ dài của các chữ cái/số để cho phép ghép nối.

Bộ định lượng là các số được viết trong dấu ngoặc nhọn { } sau ký tự mà chúng đang định lượng, ví dụ:

  • "A{2}" sẽ trả về trường hợp hai chữ cái A viết hoa.
  • "A{2,4}" sẽ trả về các trường hợp từ hai đến bốn chữ cái A viết hoa (không đặt dấu cách!).
  • "A{2,}" sẽ trả về các trường hợp từ hai hoặc nhiều hơn chữ cái A viết hoa.
  • "A+" sẽ trả về các trường hợp từ một hoặc nhiều hơn chữ cái A viết hoa (nhóm được mở rộng cho đến khi gặp một ký tự khác).
  • Bắt đầu bằng dấu hoa thị * để trả về không hoặc nhiều hơn kết quả phù hợp (hữu ích nếu bạn không chắc chắn pattern có sẵn)

Sử dụng ký hiệu dấu cộng + như một bộ định lượng, việc khớp sẽ xảy ra cho tới khi gặp ký tự khác. Ví dụ, biểu thứ này sẽ trả về tất cả các từ (ký tự alpha: "[A-Za-z]+"

# test string for quantifiers
test <- "A-AA-AAA-AAAA"

Khi bộ định lượng {2} được sử dụng, chỉ các cặp chữ A liên tiếp được trả về. Hai cặp được xác định trong AAAA.

str_extract_all(test, "A{2}")
## [[1]]
## [1] "AA" "AA" "AA" "AA"

Khi bộ định lượng {2,4} được sử dụng, các nhóm chữ A liên tiếp có độ dài từ hai đến bốn được trả về.

str_extract_all(test, "A{2,4}")
## [[1]]
## [1] "AA"   "AAA"  "AAAA"

Với bộ định lượng +, các nhóm của một hoặc nhiều hơn được trả về:

str_extract_all(test, "A+")
## [[1]]
## [1] "A"    "AA"   "AAA"  "AAAA"

Vị trí tương đối

Những biểu thức dưới đây yêu cầu cho những thứ đứng trước hoặc theo sau một mẫu. Ví dụ, để trích xuất câu, “two numbers that are followed by a period” (""). (?<=\.)\s(?=[A-Z])

str_extract_all(test, "")
## [[1]]
##  [1] "A" "-" "A" "A" "-" "A" "A" "A" "-" "A" "A" "A" "A"
Biểu thức vị trí Khớp với
"(?<=b)a" “a” bị đứng trước bởi “b”
"(?<!b)a" “a” KHÔNG bị đứng trước bởi “b”
"a(?=b)" “a” được theo sau bởi “b”
"a(?!b)" “a” KHÔNG được theo sau bởi “b”

Nhóm

Việc bắt các nhóm trong biểu thức chính quy là một cách để kết quả trả về có tổ chức hơn khi trích xuất.

Ví dụ về Regex

Dưới đây là một văn bản tự do sử dụng làm ví dụ. Chúng ta sẽ cố gắng trích xuất thông tin hữu ích từ nó bằng cách sử dụng cụm từ tìm kiếm theo biểu thức chính quy.

pt_note <- "Patient arrived at Broward Hospital emergency ward at 18:00 on 6/12/2005. Patient presented with radiating abdominal pain from LR quadrant. Patient skin was pale, cool, and clammy. Patient temperature was 99.8 degrees farinheit. Patient pulse rate was 100 bpm and thready. Respiratory rate was 29 per minute."

Biểu thức sau đây khớp với tất cả các từ (bất kỳ ký tự nào cho đến khi gặp thứ không phải ký tự, chẳng hạn như dấu cách):

str_extract_all(pt_note, "[A-Za-z]+")
## [[1]]
##  [1] "Patient"     "arrived"     "at"          "Broward"     "Hospital"    "emergency"   "ward"        "at"          "on"          "Patient"    
## [11] "presented"   "with"        "radiating"   "abdominal"   "pain"        "from"        "LR"          "quadrant"    "Patient"     "skin"       
## [21] "was"         "pale"        "cool"        "and"         "clammy"      "Patient"     "temperature" "was"         "degrees"     "farinheit"  
## [31] "Patient"     "pulse"       "rate"        "was"         "bpm"         "and"         "thready"     "Respiratory" "rate"        "was"        
## [41] "per"         "minute"

Biểu thức "[0-9]{1,2}" khớp với các số liên tiếp có độ dài 1 hoặc 2 chữ số. Nó cũng có thể được viết là "\\d{1,2}", hoặc "[:digit:]{1,2}".

str_extract_all(pt_note, "[0-9]{1,2}")
## [[1]]
##  [1] "18" "00" "6"  "12" "20" "05" "99" "8"  "10" "0"  "29"

Bạn có thể xem danh sách hữu ích về các biểu thức regex và các mẹo trên trang 2 của cheatsheet này

Bạn cũng có thể xem tutorial này.

10.9 Nguồn

Bạn có thể tìm thấy trang tham khảo cho các hàm stringr tại đây

Một vignette về stringr có thể được tìm thấy tại đây