美文网首页R语言R数据科学读书会数据-R语言-图表-决策-Linux-Python
小洁详解《R数据科学》--第十章 使用stringr处理字符串(

小洁详解《R数据科学》--第十章 使用stringr处理字符串(

作者: 小洁忘了怎么分身 | 来源:发表于2018-10-28 23:56 被阅读30次

    4.工具

    • 确定与某种模式相匹配的字符串;
    • 找出匹配的位置;
    • 提取出匹配的内容;
    • 使用新值替换匹配内容;
    • 基于匹配拆分字符串。

    4.1匹配检测

    str_detect()只返回是否符合的逻辑值,实际上计数更实用。
    x <- c("apple", "banana", "pear")
    str_detect(x, "e")
    #> [1] TRUE FALSE TRUE
    
    str_detect()和sum、mean连用,统计匹配的个数和比例。
    # 有多少个以t开头的常用单词?
    sum(str_detect(words, "^t"))#sum是计数
    #> [1] 65
    # 以元音字母结尾的常用单词的比例是多少?
    mean(str_detect(words, "[aeiou]$"))#mean是比例。[]表示任选其一
    #> [1] 0.277
    
    复杂的正则表达式可拆分为几个简单的

    找出不包含元音字母的所有单词:

    # 找出至少包含一个元音字母的所有单词,然后取反
    no_vowels_1 <- !str_detect(words, "[aeiou]")
    # 找出仅包含辅音字母(非元音字母)的所有单词
    no_vowels_2 <- str_detect(words, "^[^aeiou]+$")
    identical(no_vowels_1, no_vowels_2)
    
    匹配取子集操作
    words[str_detect(words, "x$")]#方法一,逻辑取子集
    #> [1] "box" "sex" "six" "tax"
    str_subset(words, "x$")#方法二,str_subset() 直接用取子集函数
    #> [1] "box" "sex" "six" "tax"
    

    结合filter,对数据框里的行进行匹配取子集

    df <- tibble(
      word = words,
      i = seq_along(word)
    )
    #发现用seq_along这个操作生成了行号。
    df %>%
      filter(str_detect(words, "x$"))
    
    str_count计数:每个字符串各匹配几次
    x <- c("apple", "banana", "pear")
    str_count(x, "a")
    #> [1] 1 3 1
    # 平均来看,每个单词中有多少个元音字母?
    mean(str_count(words, "[aeiou]"))
    #> [1] 1.99
    
    str_count和mutate连用,将匹配个数添加到表格新列
    df %>%
      mutate(
        vowels = str_count(word, "[aeiou]"),
        consonants = str_count(word, "[^aeiou]")
      )
    #偷偷查了一下这俩单词,元音和辅音
    

    这里就解释了我前面发现的只匹配一次的问题
    规律:str_view一个字符串只匹配一次,str_view_all匹配多次,但二者都不匹配重叠

    匹配两次而非三次

    4.3提取匹配内容

    str_subset提取匹配到的整个字符串
    #首先明确sentence是一个stringr自带向量,由字符串(句子)组成。里面星星点点带有几个颜色单词,
    #示例是从这个向量字符串中提取出颜色单词
    
    length(sentences)
    head(sentences)
    
    class(sentences)
    #>[1] "character"
    #构建匹配模式,多种颜色任选,用|连接
    colors <- c(
      "red", "orange", "yellow", "green", "blue", "purple"
    )
    
    color_match <- str_c(colors, collapse = "|")
    color_match
    
    #用str_subset匹配取子集
    
    has_color <- str_subset(sentences, color_match)
    has_color
    
    #取出匹配到多次的字符串
    more <- sentences[str_count(sentences, color_match) > 1]
    str_view_all(more, color_match)#查看所有匹配
    
    str_extrac以列表的形式返回每个字符串的匹配
    #提取每个字符串第一个匹配
    str_extract(more, color_match)
    #> [1] "blue" "green" "orange"
    #提取每个字符串所有匹配(列表形式)
    str_extract_all(more, color_match)
    #simplify = TRUE,设置匹配同等长度
    str_extract_all(more, color_match, simplify = TRUE)
    #> [,1] [,2]
    #> [1,] "blue" "red"
    #> [2,] "green" "red"
    #> [3,] "orange" "red"
    x <- c("a", "a b", "a b c")
    str_extract_all(x, "[a-z]", simplify = TRUE)
    #> [,1] [,2] [,3]
    #> [1,] "a" "" ""
    #> [2,] "a" "b" ""
    #> [3,] "a" "b" "c"
    

    4.5分组匹配

    备忘:
    • ?:0 次或1 次。
    • +:1 次或多次。
    • *:0 次或多次。

    匹配加a或the的所有单词。单词在正则表达式里定义为:至少有1 个非空格字符的字符序列

    noun <- "(a|the) ([^ ]+)" #定义匹配模式
    #|是或,[]表示任意,^表示非,+表示1次或多次
    has_noun <- sentences %>%
    str_subset(noun) %>%#取子集
    head(10)#取前十行
    has_noun %>%
    str_extract(noun)#提取每行第一个匹配,得到10个匹配结果
    #> [1] "the smooth" "the sheet" "the depth" "a chicken"
    #>  "the parked" "the sun" "the huge" "the ball"
    #>"the woman" "a helps"
    

    str_match()tidyr::extract()拆分每个字符串匹配到的第一个,拆成两个字符串。

    has_noun %>%
      str_match(noun)
    
    tibble(sentence = sentences) %>%
      tidyr::extract(
        sentence, c("article", "noun"), "(a|the) ([^ ]+)",
        remove = FALSE
      )
    

    4.7 替换匹配内容

    str_replace 只替换每个字符串匹配到的第一个
    str_replace_all替换每个字符串匹配到的所有

    x <- c("apple", "pear", "banana") 
    str_replace(x, "[aeiou]", "-")#用-替换每个字符串第一个元音
    #> [1] "-pple" "p-ar" "b-nana"
    str_replace_all(x, "[aeiou]", "-")#用-替换每个字符串所有元音
    #> [1] "-ppl-" "p--r" "b-n-n-"
    

    向量结合str_replace_all()同时执行多个替换:

    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"
    

    回溯引用分组:交换第二个单词和第三个单词的顺序:

    sentences %>%
    str_replace("([^ ]+) ([^ ]+) ([^ ]+)", "\\1 \\3 \\2") %>%
    head(5)
    #用不交换的对比一下
    sentences %>%
    head(5)
    

    4.9 str_split 拆分

    str_split()将字符串拆分为多个片段
    将句子拆分成单词

    sentences %>%
    head(5) %>%
    str_split(" ")
    

    拆分单个字符串,返回一个列表
    拆分多元素的向量,设置simplify = TRUE返回一个矩阵
    n设定拆分片段的最大数量:

    fields <- c("Name: Hadley", "Country: NZ", "Age: 35")
    fields %>% str_split(": ", n = 2, simplify = TRUE)
    

    (这里有点类似于tidyr里的separate,把一列分两列,只是separate按照分隔符来分,不同的是,如果你要分的列数比按照分隔符分的列数少,separate会把多出来的列信息丢掉,而这个不会)
    比如:

    #刚才的代码改下,有两个分隔符可分三列,可我指定分两列怎么办?
    fields <- c("Name: Hadley: ma", "Country: NZ", "Age: 35")
    fields %>% str_split(": ", n = 2, simplify = TRUE)
    

    而separate的做法会是把多出来的ma丢掉。
    用字母、行、句子和单词边界boundary()
    关于边界的探索:

    str_view_all(x, boundary("word"))
    str_view_all(x, boundary("sentence"))
    str_view_all(x, boundary("letter"))#报错
    #Error in match.arg(type) : 
    #  'arg' should be one of “character”, “line_break”, “sentence”, “word”
    str_view_all(x, boundary("character"))
    

    4.11

    str_locate() 和str_locate_all() 函数可以给出每个匹配的开始位置和结束位置。

    5.其他类型的模式

    regex()的参数

    • ignore_case = TRUE 忽略大小写
    • multiline = TRUE 分行,每行匹配一次(亲测)
    • comments = TRUE 可加注释
    • dotall = TRUE dotall = TRUE 可以使得. 匹配包括\n 在内的所有字符。

    regex(),之外的3 种函数:

    • fixed() 按照字符串的字节形式进行精确匹配,不需要转义
    • coll() 使用标准排序规则来比较字符串
    • boundary() 边界

    6.正则表达式其他应用

    apropos() 函数可以在全局环境空间中搜索所有可用对象(可以搜函数)。
    dir() 函数可以列出一个目录下的所有文件,pattern可用正则表达式匹配文件名。

    微信公众号生信星球同步更新我的文章

    友情链接:
    生信技能树公益视频合辑:学习顺序是linux,r,软件安装,geo,小技巧,ngs组学!
    B站链接:https://m.bilibili.com/space/338686099
    YouTube链接:https://m.youtube.com/channel/UC67sImqK7V8tSWHMG8azIVA/playlists
    生信工程师入门最佳指南:https://mp.weixin.qq.com/s/vaX4ttaLIa19MefD86WfUA
    学徒培养:https://mp.weixin.qq.com/s/3jw3_PgZXYd7FomxEMxFmw

    相关文章

      网友评论

      本文标题:小洁详解《R数据科学》--第十章 使用stringr处理字符串(

      本文链接:https://www.haomeiwen.com/subject/obketqtx.html