前言
實際工作中,經常需要處理字符串。R包stringr處理字符相對簡單,尤其是我常用Power BI,但是對M語言不熟悉,不會處理字符數據,往往我就先利用R清洗字符數據列。
本文記錄工作中常用的字符處理函數,部分案例照搬R for Data Science的字符部分。
Excle中自帶的字符函數如: left,len,mid,find,Proper,rept,trim,upper,substitute,concatenate,以及Excle2019新出的concat,textjoin等函數,我個人比較喜歡textjoin 函數,尤其在必須手工寫一段長向量時
學習的時候可以先用stringr包實現以上相對應功能。
資料:
字符串處理的難點,個人覺得在於【正則表達式】的掌握程度,但是需要用到正則表達式時都是比較複雜的字符處理工作,在實際商業文本數據中
運用較多。對大部分常規商業數據分析工作者的面對的表格數據而言,字符處理可能僅僅只是合併、剔除、刪除空格、倒敘等基礎操作。
R語言中字符串輸入時,可以使用單引號,也可以使用雙引號。
要在字符串中包含單引號或雙引號,可以使用\ 轉義它,即遇到特殊符號時需要轉義。
#install.packages('stringr')
library(stringr)
char <- "我是一名\'小學生\'" #字符串建議用雙引號包裹,單引號也可以
char列印會顯示轉義符。要查看字符串的原始內容,可使用writeLines()或cat()
x <- c("\"", "\\")
x
#> [1] "\"" "\\"
writeLines(x)
cat(char)
#> "
#> \在正則表達式中\ 有特殊含義,有時需要兩個\ ,多體會下面這段,代碼實現移除"||"的功能。
str_remove(string = 'a||b',pattern = "\\|\\|")另外常見的\n, \t需要被轉義處理,在字符清洗,如小說語義分析,網頁爬蟲後整理等數據清洗過程中經常用到.
字符串長度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(data.table)
dt <- data.table(col=rep('a',10),letters=letters[1:10])
dt[,newcol:=str_c(letters,collapse = '|'),by=.(col)][]# 可以多體會體會 有時候有奇用
#工作中路徑需要拆解 類似商品品類路徑 進口水果-熱帶水果-生鮮,用戶行為路徑等
dt <- data.table(col='a',letters=str_c(letters[1:10],collapse = '|'))
my_str_split <- function(x){
str_split(x,pattern = "\\|") %>% unlist() #str_split 拆解出來是列表 需要向量化
}
dt[,list(newcol=my_str_split(letters)),by=.(col)]
R4.0後新特性新特性
char <- r"(\\a\ab\d\e\f)" #windows下路徑好用,不用轉義路徑複製和直接可用
char
char <- r"(我是一名'R語言'學習者)"
cat(char)
常用函數截取字符串,匹配字符串,添加指定字符籌齊長度,去除左右兩邊空格,分割字符串,大小寫轉換等常用函數。
截取與Excle中left,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)
匹配查看函數幫助文檔,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]')
添加字符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')
去除空格與excel中trim函數功能類似,剔除字符中的空格,但是不可以剔除字符中的空格
# side 可選 both left right
str_trim(' ab af ',side = 'both')
分割字符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 ")
其他函數匹配字符串本身行篩選時候能用
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]')])
複製字符串
fruit <- c("apple", "pear", "banana")
str_dup(fruit, 2)
str_dup(fruit, 1:3)
str_c("ba", str_dup("na", 0:5))
從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")
R實現Excel字符函數以下函數實現,僅僅只是從stringr包的函數上修改,並且沒有完善,沒有報錯提示等的簡陋版本,如果感興趣的可以嘗試利用Rcpp寫出高性能版本的同功能函數。
r_left <- function(str,num){
str_sub(string = str,start = 1,end = num)
}
r_left('我是R語言學習者',3)r_right <- function(str,num){
str_sub(string = str,start = str_length(str) - num + 1)
}
r_right('我是R語言學習者',3)r_mid <- function(str,start,num){
str_sub(string = str,start = start,end = start + num -1)
}
r_mid('我是R語言學習者',3,3)其餘函數可以自行實現,歡迎留言留下實現的好用的字符處功能函數。