R-应用流行病学和公共卫生-9.字符和字符串

本页演示了使用stringr包来评估和处理字符值(“字符串”)。

  1. 合并、排序、拆分、排列 - str_c()str_glue()str_order(),str_split()
  2. 清洁和标准化
    • 调整长度 - str_pad()str_trunc(),str_wrap()
    • 更改大小写 - str_to_upper()str_to_title()str_to_lower(),str_to_sentence()
  3. 按位置评估和提取 - str_length()str_sub(),word()
  4. 模式
    • 检测和定位 - str_detect()str_subset()str_match(),str_extract()
    • 修改替换 - str_sub(),str_replace_all()
  5. 正则表达式(“正则表达式”)

为了便于显示,大多数示例都显示在一个短定义的字符向量上,但是它们可以很容易地适应数据框中的列。

这个stringr vignette为这个页面提供了很多灵感。

准备

加载包

安装或加载stringr和其他tidyverse包。

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

导入数据

在本页中,我们偶尔会参考linelist从模拟埃博拉疫情中清除的病例。如果您想继续,请单击以下载“干净”行列表(作为 .rds 文件)。使用rioimport()包中的函数导入数据(它处理许多文件类型,如 .xlsx、.csv、.rds - 有关详细信息,请参阅导入和导出页面)。

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

组合、分裂、排列

本节涵盖:

  • 使用str_c()str_glue(), 和unite()组合字符串
  • 用于str_order()排列字符串
  • 使用str_split()andseparate()分割字符串

组合字符串

要将多个字符串组合或连接成一个字符串,我们建议使用str_cfrom stringr。如果您有不同的字符值要组合,只需将它们作为唯一参数提供,用逗号分隔。

参数sep =在您提供的每个参数之间插入一个字符值(例如插入逗号、空格或换行符"\n"

collapse =如果您输入多个向量作为 的参数,则该参数是相关的str_c()。它用于分隔输出向量的元素使得输出向量只有一个长字符元素。

下面的示例显示了两个向量的组合(名字和姓氏)。另一个类似的例子可能是司法管辖区及其案件数量。在这个例子中:

  • sep =值出现在每个名字和姓氏之间
  • 价值出现collapse =在每个人之间
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"

注意:根据您所需的显示上下文,在打印带有换行符的组合字符串时,您可能需要将整个短语包装起来cat()以使换行符正确打印:

# 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

动态字符串

用于str_glue()将动态 R 代码插入字符串。这是创建动态绘图标题的非常有用的功能,如下所示。

  • 所有内容都在双引号之间str_glue("")
  • {}任何动态代码或对预定义值的引用都放在双引号内的大括号内。str_glue()同一命令中可以有多个大括号。
  • 要显示字符引号 '',请在周围的双引号内使用引号(例如,在提供日期格式时 - 参见下面的示例)
  • 提示:您可以使用\n强制换行
  • 提示:您用于format()调整日期显示,并用于Sys.Date()显示当前日期

一个简单的例子,一个动态的情节标题:

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 15 Dec 2021.

另一种格式是在括号内使用占位符并在函数末尾的单独参数中定义代码str_glue(),如下所示。如果文本很长,这可以提高代码的可读性。

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 15 Dec 2021.
## Last case hospitalized on 30 Apr 2015.
## 256 cases are missing date of onset and not shown

从数据框中拉取

有时,从数据框中提取数据并将其按顺序粘贴在一起很有用。下面是一个示例数据框。我们将使用它来对司法管辖区以及新案件和总案件数量进行简要说明。

# 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)
  )

使用str_glue_data(),它专门用于从数据框行中获取数据:

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)

跨行组合字符串

如果您尝试“汇总”数据框列中的值,例如,通过将多行中的值与分隔符粘贴在一起,将它们组合成一行,请参阅重复数据删除页面的“汇总”部分价值观

数据框到一行

str_c()您可以使用(指定数据框和列名称)以及提供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"

您可以将前缀文本“New Cases:”添加到语句的开头,方法是使用单独的换行符str_c()(如果“New Cases:”在原始文本中str_c(),它将出现多次)。

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"
## [1] "New Cases: Zone 1 = 3;  Zone 2 = 0;  Zone 3 = 7;  Zone 4 = 0;  Zone 5 = 15"

联合列

在数据框中,可以使用unite()from tidyr将来自多列的字符值组合在一起。这与separate().

提供新联合列的名称。然后提供您希望合并的列的名称。

  • 默认情况下,联合列中使用的分隔符是下划线_,但这可以通过sep =参数进行更改。
  • remove =从数据框中删除输入列(默认为 TRUE)
  • na.rm =合并时删除缺失值(默认为 FALSE)

下面,我们定义一个小型数据框来演示:

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].

下面,我们将三个症状列合并起来:

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

split

要根据模式拆分字符串,请使用str_split(). 它评估字符串并返回list由新拆分的值组成的字符向量。

下面的简单示例计算一个字符串并将其拆分为三个。默认情况下,它list为最初提供的每个字符串返回一个具有一个元素(字符向量)的类对象。如果simplify = TRUE它返回一个字符矩阵。

在此示例中,提供了一个字符串,该函数返回一个包含一个元素的列表 - 一个包含三个值的字符向量。

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

如果保存了输出,则可以使用括号语法访问第 n 个拆分值。要访问特定值,您可以使用如下语法:the_returned_object[[1]][2],它将访问第一个评估字符串(“fever”)中的第二个值。有关访问元素的更多详细信息,请参阅R 基础页面。

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

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

如果 str_split() 提供了多个字符串,则返回的列表中将有多个元素。

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"

要改为返回“字符矩阵”,这在创建数据框列时可能很有用,请simplify = TRUE按如下所示设置参数:

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"  ""

您还可以使用n =参数调整要创建的拆分数量。例如,这将拆分数限制为 2。任何进一步的逗号都保留在第二个值内。

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"

注意 - 可以使用 str_split_fixed()实现相同的输出,其中您不提供simplify参数,但必须指定列数 ( n)。

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

拆分列

如果您尝试拆分数据框列,最好使用dplyrseparate()中的函数。它用于将一个字符列拆分为其他列。

假设我们有一个简单的数据框(在unite 部分df中定义和统一),其中包含一列case_ID、一个包含许多症状的字符列和一个结果列。我们的目标是将symptoms列分成许多列——每列包含一个症状。

假设数据通过管道传输到separate(),首先提供要分离的列。然后提供一个包含into =列名称的向量,如下所示。c( )

  • sep =分隔符,可以是字符,也可以是数字(解释为要拆分的字符位置)
  • remove =默认情况下为 FALSE,删除输入列
  • convert =默认情况下为 FALSE,将导致字符串“NA”变为NA
  • extra =如果分隔创建的值多于命名的新列,这将控制发生的情况。
    • extra = "warn"意味着你会看到一个警告,但它会丢弃多余的值(默认值
    • extra = "drop"意味着超出的值将被删除而没有警告
    • extra = "merge"只会拆分为列出的新列数into-此设置将保留您的所有数据

下面是一个示例extra = "merge"- 没有数据丢失。定义了两个新列,但任何第三个症状都留在第二个新列中:

# 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

extra = "drop"下面使用默认值时,会给出警告,但会丢失第三个症状:

# 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

注意:如果您没有为into新列提供足够的值,您的数据可能会被截断。

按字母顺序排列

几个字符串可以按字母顺序排序。str_order()返回顺序,同时str_sort()按该顺序返回字符串。

# 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"

要使用不同的字母表,请添加参数locale =stringi::stri_locale_list()通过输入R 控制台查看完整的语言环境列表。

基本 R 函数

通常会看到基本R 函数paste()paste0(),它们在将所有部分转换为字符后连接向量。它们的行为类似,str_c()但语法可能更复杂 - 在括号中,每个部分用逗号分隔。这些部分是字符文本(引号)或预定义的代码对象(无引号)。例如:

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."

sep =并且collapse =可以指定参数。paste()只是paste0()带有默认值sep = " "(一个空格)。

清洁和标准化

Change case

通常必须更改字符串值的大小写/大写,例如管辖区的名称。使用stringr中的str_to_upper(),str_to_lower()​​ 和str_to_title(),如下所示:

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

使用 *base** R,也可以使用toupper(), tolower()来实现上述目标。

Title case

可以通过以下方式转换字符串,使每个单词都大写str_to_title()

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

toTitleCase()工具包中使用以实现更细微的大写(“to”、“the”和“of”等词不大写)。

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

您也可以使用str_to_sentence(),它仅将字符串的第一个字母大写。

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

Pad length

str_pad()将字符添加到字符串中,以达到最小长度。默认情况下会添加空格,但您也可以使用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...."

例如,要使用前导零填充数字(例如小时或分钟),您可以使用pad = "0"将数字填充到最小长度 2 。

# 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")

截短

str_trunc()设置每个字符串的最大长度。如果字符串超过此长度,则将其截断(缩短)并包含省略号 (...) 以指示该字符串以前更长。请注意,省略号计入长度省略号字符可以用参数更改ellipsis =。可选side =参数指定省略号将出现在截断字符串中的哪个位置(“left”、“right”或“center”)。

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

标准化长度

使用str_trunc()设置最大长度,然后使用str_pad()将非常短的字符串扩展到该截断长度。在下面的示例中,将 6 设置为最大长度(一个值被截断),然后填充一个非常短的值以达到 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   "

删除前导/尾随空格

用于str_trim()删除字符串输入两侧的空格、换行符 ( \n) 或制表符 ( )。\t"right" "left", 或添加"both"到命令以指定要修剪的一侧(例如 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"

删除重复的空格

用于str_squish()删除字符串中出现的重复空格。例如,将双空格转换为单空格。它还会删除字符串外部的空格、换行符或制表符,例如str_trim().

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

换成段落

用于str_wrap()将较长的非结构化文本包装成具有固定行长的结构化段落。为每一行提供理想的字符长度,并应用一种算法\n在段落中插入换行符 ( ),如下例所示。

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."

可以将基本函数cat()包装在上述命令周围,以便打印输出,显示添加的新行。

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.

位置处理

按字符位置提取

用于str_sub()仅返回字符串的一部分。该函数接受三个主要参数:

  1. 字符向量
  2. 起始位置
  3. 结束位置

关于位置编号的几点说明:

  • 如果位置编号为正,则从字符串的左端开始计算位置。
  • 如果位置编号为负数,则从字符串的右端开始计数。
  • 职位编号包括在内。
  • 超出字符串的位置将被截断(删除)。

以下是应用于字符串“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"

按词位提取

要提取第 n 个“单词”,请使用word(), 也来自stringr。提供字符串,然后是要提取的第一个单词位置,以及要提取的最后一个单词位置。

默认情况下,“单词”之间的分隔符假定为空格,除非另有说明sep =(例如 sep = "_",当单词用下划线分隔时。

# 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"

按字符位置替换

str_sub()与赋值运算符 ( ) 配对<-可用于修改字符串的一部分:

word <- "pneumonia"

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

# print
word
## [1] "pnXXmonia"

应用于多个字符串(例如列)的示例。注意“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"

评估长度

str_length("abc")
nchar("abc")

模式

许多stringr函数用于根据指定的模式检测、定位、提取、匹配、替换和拆分。

检测模式

如下使用str_detect()来检测字符串中模式的存在/不存在。首先提供要在 ( ) 中搜索的字符串或向量string =,然后提供要查找的模式 ( pattern =)。请注意,默认情况下搜索区分大小写

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

如果您想知道模式是否不存在,negate =可以包含该参数并将其设置为TRUE

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

要忽略大小写/大写,请将模式包装在 内regex(),并在内 regex()添加参数ignore_case = TRUE(或T作为简写形式)。

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

str_detect()应用于字符向量或数据框列时,它将为每个值返回 TRUE 或 FALSE。

# 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

如果您需要计算TRUE的个数,只需sum()输出

sum(str_detect(occupations, "teach"))

要搜索包含多个术语,请在pattern =参数中将它们用 OR  (|) 分隔,如下所示:

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

如果您需要构建一长串搜索词,您可以使用str_c()和 sep = |将它们组合起来,然后定义 this 是一个字符对象,然后稍后更简洁地引用该向量。下面的示例包括一线医疗提供者可能的职业搜索词。

# 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"

此命令返回包含一线医疗提供者 ( occupation_med_frontline) 的任一搜索词的职业数量:

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

基本 R 字符串搜索函数

基本函数的grepl()工作方式与 类似str_detect(),因为它搜索与模式的匹配项并返回一个逻辑向量。基本语法是grepl(pattern, strings_to_search, ignore.case = FALSE, ...). 一个优点是ignore.case参数更容易编写(不需要涉及regex()函数)。

同样,函数sub()gsub()行为类似于str_replace()。它们的基本语法是:gsub(pattern, replacement, strings_to_search, ignore.case = FALSE)sub()将替换模式的第一个实例,而gsub()将替换模式的所有实例。

将逗号转换为句点

这是一个使用gsub()将逗号转换为数字向量中的句点的示例。如果您的数据来自美国或英国以外的世界其他地区,这可能会很有用。

gsub()首先起作用的内部lengths是将任何句点转换为无空格“。句点字符”。必须用两个斜线“转义”才能真正表示句号,因为“.” 在正则表达式中表示“任何字符”。然后,结果(只有逗号)被传递到外部gsub(),其中逗号被句点替换。

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

全部替换

用作str_replace_all()“查找和替换”工具。首先,将要评估的字符串提供给string =,然后将要替换的模式提供给pattern =,然后将替换值提供给replacement =。下面的示例将所有“死亡”实例替换为“死亡”。请注意,这是区分大小写的。

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"

笔记:

  • 要用替换模式NA,请使用str_replace_na()
  • 该函数str_replace()仅替换每个评估字符串中模式的第一个实例。

逻辑内检测

case_when()

str_detect()经常在case_when()(来自dplyr)中使用。假设occupations是行列表中的一列。下面mutate()通过case_when()使用条件逻辑创建一个新列is_educator

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"))

提醒一下,将排除标准添加到条件逻辑 ( 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"))

定位花样位置

要定位模式的第一个位置,请使用str_locate()。它输出开始和结束位置。

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

与其他str函数一样,有一个“_all”版本 ( str_locate_all()),它将返回每个字符串中模式的所有实例的位置。这输出为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

提取匹配

str_extract_all()返回匹配的模式本身,当您通过“OR”条件提供了多个模式时,这是最有用的。例如,在职业字符串向量(参见上一个选项卡)中查找 teach”、“prof”或“tutor”。

str_extract_all()返回一个list包含每个评估字符串的所有匹配项的 a。请参阅下面的职业 3 如何在其中有两个模式匹配。

str_extract_all(occupations, "teach|prof|tutor")

str_extract()仅提取每个评估字符串中的第一个匹配项,为每个评估字符串生成一个包含一个元素的字符向量。它返回NA没有匹配的地方。NA可以通过用na.exclude()包返回的向量来删除

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

 子集和计数

对齐的函数包括str_subset()str_count()

str_subset()返回包含模式的实际值:

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

str_count()返回一个数字向量:搜索词出现在每个评估值中的次数。

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

特殊字符

反斜杠\作为转义

反斜杠\用于“转义”下一个字符的含义。这样,反斜杠可用于其他引号 ( \") 内显示引号 - 中间引号不会“破坏”周围的引号。

注意 - 因此,如果你想显示一个反斜杠,你必须用另一个反斜杠来转义它的含义。所以你必须写两个反斜杠\\来显示一个。

Special characterRepresents
"\\"backslash
"\n"a new line (newline)
"\""double-quote within double quotes
'\''single-quote within single quotes
"\| grave accent| carriage return| tab| vertical tab"`backspace

正则表达式和特殊字符

正则表达式或“regex”是一种用于描述字符串模式的简洁语言。如果您不熟悉它,正则表达式可能看起来像外星语言。在这里,我们尝试稍微揭开这种语言的神秘面纱。

本节的大部分内容改编自本教程本备忘单。我们有选择地适应这里,因为知道本手册可能会被没有互联网访问权限的人查看以查看其他教程。

正则表达式通常用于从“非结构化”文本中提取特定模式——例如医疗记录、主诉、患者病史或数据框中的其他自由文本列

有四种基本工具可以用来创建基本的正则表达式:

  1. 字符集
  2. 元字符
  3. 量词
  4. 团体

字符集

字符集是一种在括号内表示字符匹配的列表选项的方式。因此,如果在字符串中找到括号内的任何字符,则将触发任何匹配。例如,要查找元音,可以使用以下字符集:“[aeiou]”。其他一些常见的字符集是:

Character setMatches for
"[A-Z]"any single capital letter
"[a-z]"any single lowercase letter
"[0-9]"any digit
[:alnum:]any alphanumeric character
[:digit:]any numeric digit
[:alpha:]any letter (upper or lowercase)
[:upper:]any uppercase letter
[:lower:]any lowercase letter

字符集可以组合在一个括号内(没有空格!),例如"[A-Za-z]"(任何大写或小写字母),或另一个示例"[t-z0-5]"(小写 t 到 z 或数字 0 到 5)。

元字符

元字符是字符集的简写。下面列出了一些重要的:

Meta characterRepresents
"\\s"a single space
"\\w"any single alphanumeric character (A-Z, a-z, or 0-9)
"\\d"any single numeric digit (0-9)

量词

通常,您不想只搜索一个字符的匹配项。量词允许您指定字母/数字的长度以允许匹配。

{ } 量词是写在它们要量化的字符之后的大括号内的数字,例如,

  • "A{2}"将返回两个大写 A 字母的实例。
  • "A{2,4}"将返回两到四个大写 A 字母的实例(不要放空格!)
  • "A{2,}"将返回两个或多个大写 A 字母的实例。
  • "A+"将返回一个或多个大写 A 字母的实例(扩展组直到遇到不同的字符)。
  • *星号开头以返回零个或多个匹配项(如果您不确定模式是否存在,则很有用)

使用+加号作为量词,匹配将一直发生,直到遇到不同的字符。例如,此表达式将返回所有单词(字母字符:"[A-Za-z]+")

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

当使用量词 {2} 时,只返回成对的连续 A。内标识了两对AAAA

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

当使用量词 {2,4} 时,将返回长度为 2 到 4 的连续 A 组。

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

使用量词+,返回一个或多个组:

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

相对位置

这些表达了对模式之前或之后的要求。例如,要提取句子,“两个数字后跟一个句点”("")。(?<=\.)\s(?=[AZ])

str_extract_all(test, "")
## [[1]]
##  [1] "A" "-" "A" "A" "-" "A" "A" "A" "-" "A" "A" "A" "A"
Position statementMatches to
"(?<=b)a"“a” that is preceded by a “b”
"(?<!b)a"“a” that is NOT preceded by a “b”
"a(?=b)"“a” that is followed by a “b”
"a(?!b)"“a” that is NOT followed by a “b”

Groups

在正则表达式中捕获组是一种在提取时获得更有条理的输出的方法。

正则表达式示例

以下是示例的免费文本。我们将尝试使用正则表达式搜索词从中提取有用的信息。

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."

此表达式匹配所有单词(任何字符,直到遇到诸如空格之类的非字符):

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

该表达式"[0-9]{1,2}"匹配长度为 1 或 2 位的连续数字。也可以写成"\\d{1,2}", 或"[: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"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值