4.2 stringr

本小节介绍R包stringr,stringr处理字符相对简单,并且是tidyverse系列的一部分,是很成熟的R包,API功能稳定。stringr是基于stringi之上构建的,stringr包集合了常见字符功能函数,如果发现stringr缺少某些功能可以查看stringi包。

如上文所说,字符串处理的难点,个人觉得在于正则表达式的掌握程度。对大部分常规商业数据分析工作者的面对的表格数据而言,字符处理可能仅仅只是合并、剔除、删除空格、倒叙等基础操作,所以stringr包基本满足字符处理需求。

stringr项目地址:https://github.com/tidyverse/stringr/

如果不熟悉R中的字符串,可以从R for Data Science的字符串部分开始学习,

本小节的部分案例照搬R for Data Science

4.2.1 安装

# Install the released version from CRAN:
install.packages("stringr")

# Install the cutting edge development version from GitHub:
# install.packages("devtools")
devtools::install_github("tidyverse/stringr")

4.2.2 基本使用

stringr包中所有的函数都已str_开头,让字符做第一个参数。

  • 字符串长度
library(stringr)
char <- "我是R语言学习者"
str_length(char)
# 向量化
str_length(c("a", "R for data science", NA))
  • 连接字符串

R中字符串不像python中可以用加号连接字符串,如下所示:

R 版本

#base R
paste0('a','b')

#stringr
str_c("a","b")
str_c("a", "b", sep = ", ") #sep 参数控制分隔符

Python 版本

'a' + 'b'

多个字符串合并为一个字符,stringr中的函数都是向量化的,合并一个和多个字符都是同样道理。

#base R
paste0(c('a','b','d','e'),collapse = ',')
#stringr
str_c(c('a','b','d','e'),collapse = ',')  #collapse 参数控制
  • 移除

在正则表达式中 有特殊含义,有时需要两个 ,多体会下面这段,代码实现移除“||”的功能。

library(stringr)
str_remove(string = 'a||b',pattern = "\\|\\|")

另外常见的\n, \t需要被转义处理,在字符清洗,如小说语义分析,网页爬虫后整理等数据清洗过程中经常用到.

4.2.3 常用函数

4.2.3.1 截取字符

Excleleft,mid,right函数功能类似

str_sub() 函数 三个参数:

string:需要被截取的字符串

start: 默认1L,即从最开始截取

end:默认-1L,即截取到最后

#注意end 3 和 -3的区别
str_sub(string = '我是R语言学习者',start = 2,end = 3)
str_sub(string = '我是R语言学习者',start = 2,end = -3)

4.2.3.2 匹配字符

查看函数帮助文档,str_match()按照指定pattern(正则表达式)查找字符。困难点在于正则表达式的编写。

?str_match()
?str_match_all()
?str_extract()
?str_extract_all()

str_extract()函数返回向量,str_match()函数返回矩阵.

#原文来源烽火戏诸侯的<剑来>
strings <- c('陈平安放下新折的那根桃枝,吹灭蜡烛,走出屋子后,坐在台阶上,仰头望去,星空璀璨.') 
str_extract(strings,'陈平安')
str_match(strings,'陈平安')
  • 匹配中文

匹配中文的正则表达式\[\u4e00-\u9fa5\]

str_extract_all(strings,'[\u4e00-\u9fa5]') #返回list
  • 匹配数字或英文

查找数字的正则表达式[0-9];查找英文的正则表达式:[a-zA-Z]

strings <- c('00123545','LOL league of legends')
str_extract_all(strings,'[0-9]')
str_extract_all(strings,'[a-zA-Z]') 

4.2.3.3 添加字符

str_pad() 函数向字符串添加字符

像工作中处理月份的时候,1,2,3,4,5,6,7,8,9,10,11,12变成01,02,03,04,05,06,07,08,09,10,11,12.按照日期时间输出文件名称,如下所示:

str_pad(string = 1:12,width = 2,side = 'left',pad = '0')

4.2.3.4 去除空格

exceltrim函数功能类似,剔除字符中的空格,但是不可以剔除字符中的空格

# side 可选 both  left right
str_trim(' ab af ',side = 'both')

4.2.3.5 分割字符

str_split()处理后的结果是列表

# 得到列表,需要向量化
str_split("a,b,d,e",pattern = ',')

str_split('ab||cd','\\|\\|') %>% unlist()
# same above
#str_split('ab||cd','\\|\\|') %>% purrr::as_vector()

当待处理的字符串是字符串向量时,得到的列表长度与向量长度一致

fruits <- c(
  "apples and oranges and pears and bananas",
  "pineapples and mangos and guavas"
)

str_split(fruits, " and ")

4.2.3.6 替换字符

str_replace()str_replace_all()函数用来替换字符

fruits <- c("one apple", "two pears", "three bananas")
str_replace(fruits, "[aeiou]", "-")
str_replace_all(fruits, "[aeiou]", "-")

4.2.3.7 移除字符

str_remove(),str_remove_all()移除字符。本人常用该函数剔除文本中的空格。

fruits <- c("one apple", "two pears", "three bananas")
str_remove(fruits, "[aeiou]")
str_remove_all(fruits, "[aeiou]")

移除文本中空格

str_replace_all(string = ' d a  b ',pattern = ' ',replacement = '')

4.2.3.8 字符排序

numeric参数决定是否按照数字排序。

str_order(x, decreasing = FALSE, na_last = TRUE, locale = "en",
  numeric = FALSE, ...)

str_sort(x, decreasing = FALSE, na_last = TRUE, locale = "en",
  numeric = FALSE, ...)
str_order(letters)
str_sort(letters)

numeric参数

x <- c("100a10", "100a5", "2b", "2a")
str_sort(x)
str_sort(x, numeric = TRUE)

4.2.3.9 提取单词

从句子中提取单词。

  • 参数
word(string, start = 1L, end = start, sep = fixed(" "))
  • 案例
sentences <- c("Jane saw a cat", "Jane sat down")
word(sentences, 2, -1)
word(sentences[1], 1:3, -1)

指定分隔符

# Can define words by other separators
str <- 'abc.def..123.4568.999'
word(str, 1, sep = fixed('..'))
word(str, 2, sep = fixed('..'))

4.2.3.10 其他函数

  • str_subset() str_which()

匹配字符串本身行筛选时候能用


fruit <- c("apple", "banana", "pear", "pinapple")
str_subset(fruit, "a")
str_which(fruit, "a") # 匹配字符首次出现的位置
#str_which 是which(str_detect(x,pattern))的包装
#str_which()

#str_subset是对x[str_detect(x,pattern)]的包装
#str_subset()

#筛选出字母行
set.seed(24)
dt <- data.table::data.table(col=sample(c(letters,1:10),100,replace = T))
head(dt[str_which(col,pattern = '[a-z]')])
  • str_dup()

复制字符串

fruit <- c("apple", "pear", "banana")
str_dup(fruit, 2)
str_dup(fruit, 1:3)
str_c("ba", str_dup("na", 0:5))
  • str_starts() str_ends()

从str_detect()包装得到.

str_starts('abd','a')
str_detect('abd','^a')

str_ends('abd','d')
str_detect('abd','a$')
  • 大小写转换
dog <- "The quick brown dog"
str_to_upper(dog)
str_to_lower(dog)
str_to_title(dog)
str_to_sentence("the quick brown dog")