0%

Stringr包处理字符串

前段时间终于结束了一些事情,一个月来没好好坐下来看些资料了,接下来打算把之前计划的事情都一一完成下,先从stringr包开始,这个R语言的工具包值得做些笔记以便平时自己的查询及使用(记性不太好),可以提高不少处理数据的效率

stringr包有众多处理字符串的函数,一般都是以str_开头命名,非常好理解和记忆;相对一些相同功能的基础函数,其更加高效及便捷 下面以官方文档https://cran.r-project.org/web/packages/stringr/vignettes/stringr.html以及一些网上教程做个简单的整理

字符串处理

获取字符串长度str_length(),对应的基础函数是nchar()

str_length("abc")
[1] 3

截取字符串str_sub(),对应的基础函数是substr(),常见的如下:

x <- c("abcdef", "ghifjk")
str_sub(x, 3, 3)
[1] "c" "i"

而我们也可用其来修改字符串,如果是赋值NA则需加上omit_na = TRUE参数(不然输出值均为NA了)

x1 <- x2 <- x3 <- c("abcdef", "ghifjk")
str_sub(x1, 3, 3) <- "X"
x1
[1] "abXdef" "ghXfjk"
str_sub(x2, 2, 2) <- NA
x2
[1] NA NA
str_sub(x3, 2, 2, omit_na = TRUE) <- NA
x3
[1] "abcdef" "ghifjk"

赋值字符串str_dup(),对应的基础函数应该是rep()加上paste(),但str_dup()更加好用,如:

str_dup("abc", c(2, 3))
[1] "abcabc"    "abcabcabc"

字符串拼接str_c(),其参数与paste()一样,均有sep(把多个字符串拼接为一个大的字符串)以及collapse(把多个向量参数拼接为一个大的字符串),但对于NA的处理有点差别:paste会NA当做字符串'NA',而str_c则需要先做一个NA的转化,如:

paste("a","b",NA,sep="")
[1] "abNA"
tr_c("a", "b", str_replace_na(NA))
[1] "abNA"

字符串-空白的添加、删除及修改

对于whitespace的操作我不太常用,唯一用过的是截断长字符,用str_trunc()

x <- c("Short", "This is a long string")
str_trunc(x, 10)
[1] "Short"      "This is..."

添加空格使字符串变成固定长度str_pad(),默认是添加在左边;但其不会缩断字符串长度,尽管你参数设置小于字符串长度(PS.由于该特性,其与str_trunc()搭配使用可确保所有字符串有相同长度)

str_pad(c("aa", "bbccee"), 4)
[1] "  aa"   "bbccee"

str_trim()可实现与上述相反的功能-删除空白以及tab分隔符,默认也是两边均删除

str_trim("  abc  ")
[1] "abc"

str_wrap()可实现长段文字段落化

字符串变换-大小写转化及排序

str_to_upper()str_to_lower()可实现大写和小写的转化,对应的基础函数则是toupper()tolower()

x <- "I like horses."
str_to_upper(x)
[1] "I LIKE HORSES."
str_to_lower(x)
[1] "i like horses."

另外还有转化为标题(首字母大写)的str_to_title()

str_to_title(x)
[1] "I Like Horses."

如果是非英文的则需设置local参数,以stringi::stri_locale_list()查看其可选项

str_order()str_sort()对应基础函数order()sort(),因此比较好理解,而且也支持local参数

str_conv()可支持字符串的编码转化,相见恨晚的函数,对于一些中文乱码的情况非常好用(尤其是window系统下)

字符串的正则匹配

正则匹配在常规数据处理过程中是一个必不可少的技能,这也是我喜欢用stringr包的重要原因,其对标的是基础函数grep()/grepl()/gregexpr()/sub()

str_detect()判断是否匹配上,对应grepl()

x <- c("abcdef", "ghifjk")
str_detect(x, "a")
[1]  TRUE FALSE

str_subset()返回匹配上的元素,对应grep()

str_subset(x, "abc")
[1] "abcdef"

str_locate()返回匹配上字符串的位置,对应gregexpr()

str_locate(x, "cde")
    start end
[1,]     3   5
[2,]    NA  NA

有些stringr包的函数默认是返回第一次匹配的结果,如果要返回所有匹配的,需要加all后缀的函数(还有几个函数也类似),如:

str_locate_all(c("abcdefabc", "ghifjkabc"), "abc")
[[1]]
     start end
[1,]     1   3
[2,]     7   9

[[2]]
     start end
[1,]     7   9

str_extract()str_subset相似但略有区别,其返回的是匹配上的字符串,无匹配上的则返回NA;str_extract_all有个simplify参数能矩阵格式的结果(默认是list格式)

str_extract(x, "abc")
[1] "abc" NA 

str_match()返回你正则表达式中需要捕获的字符串;比如你抓取c("aa11bb22cc", "aa11bb33cc")这字符串中的22和33数字,如果单纯用str_extract是不行的,用基础函数sub倒是可以,但略微有点麻烦,如:

sub("\\w+[a-z](\\d+)[a-z]+", "\\1", "aa11bb22cc")
[1] "22"

但是用str_match()的话就比较直观简单了,其第一列是完全匹配的字符串,第二列开始则是捕获的,非常好用!如:

str_match("aa11bb22cc", "\\w+[a-z](\\d+)([a-z]+)")
     [,1]         [,2] [,3]
[1,] "aa11bb22cc" "22" "cc"

str_replace()用法跟基础函数sub()非常相似,都是将匹配上的字符串做个替换

str_replace("apple", "a", "xx")
[1] "xxpple"

如果是替换成空,那么可以考虑用str_remove(),相当于str_replace(string, pattern, "")

除了上述外,还有些简单且有效的函数,比如:

str_count返回匹配上数目

str_count("aabbcc", "a")
[1] 2

str_split()类似于基础函数strsplit(),分割字符串,用法也一样;但是还有个str_split_fixed可以指定分割成数目,而前两者是没这个功能的,如:

str_split_fixed("a-b-c", "-", n = 2)
    [,1] [,2] 
[1,] "a"  "b-c"

除了上述提到的正则匹配外,stringr包还有其他的Engines:

  • fixed(): match exact bytes(处理bytes的)
  • coll(): match human letters(默认是对不同语言的字母敏感,不然需加ignore_case参数)
  • boundary(): match boundaries(用于处理characters、lines、sentences 、words)

对于boundary可以看个例子:

x <- "This is a sentence."
str_split(x, boundary("word"))
[[1]]
[1] "This"     "is"       "a"        "sentence"

所以一般我们常见的相当于boundary("character")

如需完整版的函数介绍,可看stringr包的chetsheet: https://github.com/rstudio/cheatsheets/blob/master/strings.pdf

参考资料:
R----stringr包介绍学习
https://www.rdocumentation.org/packages/stringr/versions/1.4.0

本文出自于http://www.bioinfo-scrounger.com转载请注明出处