stringr包字元處理函式簡介
R的極客理想系列文章,涵蓋了R的思想,使用,工具,創新等的一系列要點,以我個人的學習和體驗去詮釋R的強大。
R語言作為統計學一門語言,一直在小眾領域閃耀著光芒。直到大資料的爆發,R語言變成了一門炙手可熱的資料分析的利器。隨著越來越多的工程背景的人的加入,R語言的社群在迅速擴大成長。現在已不僅僅是統計領域,教育,銀行,電商,網際網路….都在使用R語言。
要成為有理想的極客,我們不能停留在語法上,要掌握牢固的數學,概率,統計知識,同時還要有創新精神,把R語言發揮到各個領域。讓我們一起動起來吧,開始R的極客理想。
關於作者:
- 張丹(Conan), 程式設計師Java,R,PHP,Javascript
- weibo:@Conan_Z
- blog: http://blog.fens.me
- email: [email protected]
前言
用R語言處理字串,總覺得很麻煩,即不能用向量的方法進行分割,也不能用迴圈遍歷索引。grep()家族函式常常記不住,paste()函式預設以空格分割,各種不順手啊!隨著使用R語言的場景越來越多,字串處理是必不可少的。給大家推薦一個由 Hadley Wickham 開發的一個靈活的字串處理包stringr。
目錄
- stringr介紹
- stringr安裝
- stringr的API介紹
1. stringr介紹
stringr包被定義為一致的、簡單易用的字串工具集。所有的函式和引數定義都具有一致性,比如,用相同的方法進行NA處理和0長度的向量處理。
字串處理雖然不是R語言中最主要的功能,卻也是必不可少的,資料清洗、視覺化等的操作都會用到。對於R語言本身的base包提供的字串基礎函式,隨著時間的積累,已經變得很多地方不一致,不規範的命名,不標準的引數定義,很難看一眼就上手使用。字串處理在其他語言中都是非常方便的事情,R語言在這方面確實落後了。stringr包就是為了解決這個問題,讓字串處理變得簡單易用,提供友好的字串操作介面。
2. stringr安裝
本文所使用的系統環境
- Win10 64bit
- R: 3.2.3 x86_64-w64-mingw32/x64 b4bit
stringr是在CRAN釋出的標準庫,安裝起來非常簡單,2條命令就可以了。
~ R
> install.packages('stringr')
> library(stringr)
3. stringr的API介紹
stringr包1.0.0版本,一共提供了30個函式,方便我們對字串處理。常用的字串的處理以str_開頭來命名,方便更直觀理解函式的定義。我們可以根據使用習慣對函式進行分類:
字串拼接函式
- str_c: 字串拼接。
- str_join: 字串拼接,同str_c。
- str_trim: 去掉字串的空格和TAB(\t)
- str_pad: 補充字串的長度
- str_dup: 複製字串
- str_wrap: 控制字串輸出格式
- str_sub: 擷取字串
- str_sub<- 擷取字串,並賦值,同str_sub
字串計算函式
- str_count: 字串計數
- str_length: 字串長度
- str_sort: 字串值排序
- str_order: 字串索引排序,規則同str_sort
字串匹配函式
- str_split: 字串分割
- str_split_fixed: 字串分割,同str_split
- str_subset: 返回匹配的字串
- word: 從文字中提取單詞
- str_detect: 檢查匹配字串的字元
- str_match: 從字串中提取匹配組。
- str_match_all: 從字串中提取匹配組,同str_match
- str_replace: 字串替換
- str_replace_all: 字串替換,同str_replace
- str_replace_na:把NA替換為NA字串
- str_locate: 找到匹配的字串的位置。
- str_locate_all: 找到匹配的字串的位置,同str_locate
- str_extract: 從字串中提取匹配字元
- str_extract_all: 從字串中提取匹配字元,同str_extract
字串變換函式
- str_conv: 字元編碼轉換
- str_to_upper: 字串轉成大寫
- str_to_lower: 字串轉成小寫,規則同str_to_upper
- str_to_title: 字串轉成首字母大寫,規則同str_to_upper
引數控制函式,僅用於構造功能的引數,不能獨立使用。
- boundary: 定義使用邊界
- coll: 定義字串標準排序規則。
- fixed: 定義用於匹配的字元,包括正則表示式中的轉義符
- regex: 定義正則表示式
3.1 字串拼接函式
3.1.1 str_c,字串拼接操作,與str_join完全相同,與paste()行為不完全一致。
函式定義:
str_c(..., sep = "", collapse = NULL)
str_join(..., sep = "", collapse = NULL)
引數列表:
- …: 多引數的輸入
- sep: 把多個字串拼接為一個大的字串,用於字串的分割符。
- collapse: 把多個向量引數拼接為一個大的字串,用於字串的分割符。
把多個字串拼接為一個大的字串。
> str_c('a','b')
[1] "ab"
> str_c('a','b',sep='-')
[1] "a-b"
> str_c(c('a','a1'),c('b','b1'),sep='-')
[1] "a-b" "a1-b1"
把多個向量引數拼接為一個大的字串。
> str_c(head(letters), collapse = "")
[1] "abcdef"
> str_c(head(letters), collapse = ", ")
[1] "a, b, c, d, e, f"
# collapse引數,對多個字串無效
> str_c('a','b',collapse = "-")
[1] "ab"
> str_c(c('a','a1'),c('b','b1'),collapse='-')
[1] "ab-a1b1"
拼接有NA值的字串向量時,NA還是NA
> str_c(c("a", NA, "b"), "-d")
[1] "a-d" NA "b-d"
對比str_c()函式和paste()函式之間的不同點。
# 多字串拼接,預設的sep引數行為不一致
> str_c('a','b')
[1] "ab"
> paste('a','b')
[1] "a b"
# 向量拼接字串,collapse引數的行為一致
> str_c(head(letters), collapse = "")
[1] "abcdef"
> paste(head(letters), collapse = "")
[1] "abcdef"
#拼接有NA值的字串向量,對NA的處理行為不一致
> str_c(c("a", NA, "b"), "-d")
[1] "a-d" NA "b-d"
> paste(c("a", NA, "b"), "-d")
[1] "a -d" "NA -d" "b -d"
3.1.2 str_trim:去掉字串的空格和TAB(\t)
函式定義:
str_trim(string, side = c("both", "left", "right"))
引數列表:
- string: 字串,字串向量。
- side: 過濾方式,both兩邊都過濾,left左邊過濾,right右邊過濾
去掉字串的空格和TAB(\t)
#只過濾左邊的空格
> str_trim(" left space\t\n",side='left')
[1] "left space\t\n"
#只過濾右邊的空格
> str_trim(" left space\t\n",side='right')
[1] " left space"
#過濾兩邊的空格
> str_trim(" left space\t\n",side='both')
[1] "left space"
#過濾兩邊的空格
> str_trim("\nno space\n\t")
[1] "no space"
3.1.3 str_pad:補充字串的長度
函式定義:
str_pad(string, width, side = c("left", "right", "both"), pad = " ")
引數列表:
- string: 字串,字串向量。
- width: 字串填充後的長度
- side: 填充方向,both兩邊都填充,left左邊填充,right右邊填充
- pad: 用於填充的字元
補充字串的長度。
# 從左邊補充空格,直到字串長度為20
> str_pad("conan", 20, "left")
[1] " conan"
# 從右邊補充空格,直到字串長度為20
> str_pad("conan", 20, "right")
[1] "conan "
# 從左右兩邊各補充空格,直到字串長度為20
> str_pad("conan", 20, "both")
[1] " conan "
# 從左右兩邊各補充x字元,直到字串長度為20
> str_pad("conan", 20, "both",'x')
[1] "xxxxxxxconanxxxxxxxx"
3.1.4 str_dup: 複製字串
函式定義:
str_dup(string, times)
引數列表:
- string: 字串,字串向量。
- times: 複製數量
複製一個字串向量。
> val <- c("abca4", 123, "cba2")
# 複製2次
> str_dup(val, 2)
[1] "abca4abca4" "123123" "cba2cba2"
# 按位置複製
> str_dup(val, 1:3)
[1] "abca4" "123123" "cba2cba2cba2"
3.1.5 str_wrap,控制字串輸出格式
函式定義:
str_wrap(string, width = 80, indent = 0, exdent = 0)
引數列表:
- string: 字串,字串向量。
- width: 設定一行所佔的寬度。
- indent: 段落首行的縮排值
- exdent: 段落非首行的縮排值
txt<-'R語言作為統計學一門語言,一直在小眾領域閃耀著光芒。直到大資料的爆發,R語言變成了一門炙手可熱的資料分析的利器。隨著越來越多的工程背景的人的加入,R語言的社群在迅速擴大成長。現在已不僅僅是統計領域,教育,銀行,電商,網際網路….都在使用R語言。'
# 設定寬度為40個字元
> cat(str_wrap(txt, width = 40), "\n")
R語言作為統計學一門語言,一直在小眾領域
閃耀著光芒。直到大資料的爆發,R語言變成
了一門炙手可熱的資料分析的利器。隨著越來
越多的工程背景的人的加入,R語言的社群在
迅速擴大成長。現在已不僅僅是統計領域,教
育,銀行,電商,網際網路….都在使用R語言。
# 設定寬度為60字元,首行縮排2字元
> cat(str_wrap(txt, width = 60, indent = 2), "\n")
R語言作為統計學一門語言,一直在小眾領域閃耀著光芒。直到大數
據的爆發,R語言變成了一門炙手可熱的資料分析的利器。隨著越來
越多的工程背景的人的加入,R語言的社群在迅速擴大成長。現在已
不僅僅是統計領域,教育,銀行,電商,網際網路….都在使用R語言。
# 設定寬度為10字元,非首行縮排4字元
> cat(str_wrap(txt, width = 10, exdent = 4), "\n")
R語言作為
統計學一
門語言,
一直在小
眾領域閃
耀著光芒。
直到大資料
的爆發,R
語言變成了
一門炙手可
熱的資料分
析的利器。
隨著越來
越多的工程
背景的人的
加入,R語
言的社群在
迅速擴大成
長。現在已
不僅僅是統
計領域,教
育,銀行,
電商,互聯
網….都在使
用R語言。
3.1.6 str_sub,擷取字串
函式定義:
str_sub(string, start = 1L, end = -1L)
引數列表:
- string: 字串,字串向量。
- start : 開始位置
- end : 結束位置
擷取字串。
> txt <- "I am Conan."
# 擷取1-4的索引位置的字串
> str_sub(txt, 1, 4)
[1] "I am"
# 擷取1-6的索引位置的字串
> str_sub(txt, end=6)
[1] "I am C"
# 擷取6到結束的索引位置的字串
> str_sub(txt, 6)
[1] "Conan."
# 分2段擷取字串
> str_sub(txt, c(1, 4), c(6, 8))
[1] "I am C" "m Con"
# 通過負座標擷取字串
> str_sub(txt, -3)
[1] "an."
> str_sub(txt, end = -3)
[1] "I am Cona"
對擷取的字串進行賦值。
> x <- "AAABBBCCC"
# 在字串的1的位置賦值為1
> str_sub(x, 1, 1) <- 1; x
[1] "1AABBBCCC"
# 在字串從2到-2的位置賦值為2345
> str_sub(x, 2, -2) <- "2345"; x
[1] "12345C"
3.2 字串計算函式
3.2.1 str_count, 字串計數
函式定義:
str_count(string, pattern = "")
引數列表:
- string: 字串,字串向量。
- pattern: 匹配的字元。
對字串中匹配的字元計數
> str_count('aaa444sssddd', "a")
[1] 3
對字串向量中匹配的字元計數
> fruit <- c("apple", "banana", "pear", "pineapple")
> str_count(fruit, "a")
[1] 1 3 1 1
> str_count(fruit, "p")
[1] 2 0 1 3
對字串中的'.'字元計數,由於.是正則表示式的匹配符,直接判斷計數的結果是不對的。
> str_count(c("a.", ".", ".a.",NA), ".")
[1] 2 1 3 NA
# 用fixed匹配字元
> str_count(c("a.", ".", ".a.",NA), fixed("."))
[1] 1 1 2 NA
# 用\\匹配字元
> str_count(c("a.", ".", ".a.",NA), "\\.")
[1] 1 1 2 NA
3.2.2 str_length,字串長度
函式定義:
str_length(string)
引數列表:
- string: 字串,字串向量。
計算字串的長度:
> str_length(c("I", "am", "張丹", NA))
[1] 1 2 2 NA
3.2.3 str_sort, 字串值排序,同str_order索引排序
函式定義:
str_sort(x, decreasing = FALSE, na_last = TRUE, locale = "", ...)
str_order(x, decreasing = FALSE, na_last = TRUE, locale = "", ...)
引數列表:
- x: 字串,字串向量。
- decreasing: 排序方向。
- na_last:NA值的存放位置,一共3個值,TRUE放到最後,FALSE放到最前,NA過濾處理
- locale:按哪種語言習慣排序
對字串值進行排序。
# 按ASCII字母排序
> str_sort(c('a',1,2,'11'), locale = "en")
[1] "1" "11" "2" "a"
# 倒序排序
> str_sort(letters,decreasing=TRUE)
[1] "z" "y" "x" "w" "v" "u" "t" "s" "r" "q" "p" "o" "n" "m" "l" "k" "j" "i" "h"
[20] "g" "f" "e" "d" "c" "b" "a"
# 按拼音排序
> str_sort(c('你','好','粉','絲','日','志'),locale = "zh")
[1] "粉" "好" "你" "日" "絲" "志"
對NA值的排序處理
#把NA放最後面
> str_sort(c(NA,'1',NA),na_last=TRUE)
[1] "1" NA NA
#把NA放最前面
> str_sort(c(NA,'1',NA),na_last=FALSE)
[1] NA NA "1"
#去掉NA值
> str_sort(c(NA,'1',NA),na_last=NA)
[1] "1"
3.3 字串匹配函式
3.3.1 str_split,字串分割,同str_split_fixed
函式定義:
str_split(string, pattern, n = Inf)
str_split_fixed(string, pattern, n)
引數列表:
- string: 字串,字串向量。
- pattern: 匹配的字元。
- n: 分割個數
對字串進行分割。
> val <- "abc,123,234,iuuu"
# 以,進行分割
> s1<-str_split(val, ",");s1
[[1]]
[1] "abc" "123" "234" "iuuu"
# 以,進行分割,保留2塊
> s2<-str_split(val, ",",2);s2
[[1]]
[1] "abc" "123,234,iuuu"
# 檢視str_split()函式操作的結果型別list
> class(s1)
[1] "list"
# 用str_split_fixed()函式分割,結果型別是matrix
> s3<-str_split_fixed(val, ",",2);s3
[,1] [,2]
[1,] "abc" "123,234,iuuu"
> class(s3)
[1] "matrix"
3.3.2 str_subset:返回的匹配字串
函式定義:
str_subset(string, pattern)
引數列表:
- string: 字串,字串向量。
- pattern: 匹配的字元。
> val <- c("abc", 123, "cba")
# 全文匹配
> str_subset(val, "a")
[1] "abc" "cba"
# 開頭匹配
> str_subset(val, "^a")
[1] "abc"
# 結尾匹配
> str_subset(val, "a$")
[1] "cba"
3.3.3 word, 從文字中提取單詞
函式定義:
word(string, start = 1L, end = start, sep = fixed(" "))
引數列表:
- string: 字串,字串向量。
- start: 開始位置。
- end: 結束位置。
- sep: 匹配字元。
> val <- c("I am Conan.", "http://fens.me, ok")
# 預設以空格分割,取第一個位置的字串
> word(val, 1)
[1] "I" "http://fens.me,"
> word(val, -1)
[1] "Conan." "ok"
> word(val, 2, -1)
[1] "am Conan." "ok"
# 以,分割,取第一個位置的字串
> val<-'111,222,333,444'
> word(val, 1, sep = fixed(','))
[1] "111"
> word(val, 3, sep = fixed(','))
[1] "333"
3.3.4 str_detect匹配字串的字元
函式定義:
str_detect(string, pattern)
引數列表:
- string: 字串,字串向量。
- pattern: 匹配字元。
> val <- c("abca4", 123, "cba2")
# 檢查字串向量,是否包括a
> str_detect(val, "a")
[1] TRUE FALSE TRUE
# 檢查字串向量,是否以a為開頭
> str_detect(val, "^a")
[1] TRUE FALSE FALSE
# 檢查字串向量,是否以a為結尾
> str_detect(val, "a$")
[1] FALSE FALSE FALSE
3.3.6 str_match,從字串中提取匹配組
函式定義:
str_match(string, pattern)
str_match_all(string, pattern)
引數列表:
- string: 字串,字串向量。
- pattern: 匹配字元。
從字串中提取匹配組
> val <- c("abc", 123, "cba")
# 匹配字元a,並返回對應的字元
> str_match(val, "a")
[,1]
[1,] "a"
[2,] NA
[3,] "a"
# 匹配字元0-9,限1個,並返回對應的字元
> str_match(val, "[0-9]")
[,1]
[1,] NA
[2,] "1"
[3,] NA
# 匹配字元0-9,不限數量,並返回對應的字元
> str_match(val, "[0-9]*")
[,1]
[1,] ""
[2,] "123"
[3,] ""
從字串中提取匹配組,以字串matrix格式返回
> str_match_all(val, "a")
[[1]]
[,1]
[1,] "a"
[[2]]
[,1]
[[3]]
[,1]
[1,] "a"
> str_match_all(val, "[0-9]")
[[1]]
[,1]
[[2]]
[,1]
[1,] "1"
[2,] "2"
[3,] "3"
[[3]]
[,1]
3.3.7 str_replace,字串替換
函式定義:
str_replace(string, pattern, replacement)
引數列表:
- string: 字串,字串向量。
- pattern: 匹配字元。
- replacement: 用於替換的字元。
> val <- c("abc", 123, "cba")
# 把目標字串第一個出現的a或b,替換為-
> str_replace(val, "[ab]", "-")
[1] "-bc" "123" "c-a"
# 把目標字串所有出現的a或b,替換為-
> str_replace_all(val, "[ab]", "-")
[1] "--c" "123" "c--"
# 把目標字串所有出現的a,替換為被轉義的字元
> str_replace_all(val, "[a]", "\1\1")
[1] "\001\001bc" "123" "cb\001\001"
3.3.8 str_replace_na把NA替換為NA字串
函式定義:
str_replace_na(string, replacement = "NA")
引數列表:
- string: 字串,字串向量。
- replacement : 用於替換的字元。
把NA替換為字串
> str_replace_na(c(NA,'NA',"abc"),'x')
[1] "x" "NA" "abc"
3.3.9 str_locate,找到的模式在字串中的位置。
函式定義:
str_locate(string, pattern)
str_locate_all(string, pattern)
引數列表:
- string: 字串,字串向量。
- pattern: 匹配字元。
> val <- c("abca", 123, "cba")
# 匹配a在字串中的位置
> str_locate(val, "a")
start end
[1,] 1 1
[2,] NA NA
[3,] 3 3
# 用向量匹配
> str_locate(val, c("a", 12, "b"))
start end
[1,] 1 1
[2,] 1 2
[3,] 2 2
# 以字串matrix格式返回
> str_locate_all(val, "a")
[[1]]
start end
[1,] 1 1
[2,] 4 4
[[2]]
start end
[[3]]
start end
[1,] 3 3
# 匹配a或b字元,以字串matrix格式返回
> str_locate_all(val, "[ab]")
[[1]]
start end
[1,] 1 1
[2,] 2 2
[3,] 4 4
[[2]]
start end
[[3]]
start end
[1,] 2 2
[2,] 3 3
3.3.10 str_extract從字串中提取匹配模式
函式定義:
str_extract(string, pattern)
str_extract_all(string, pattern, simplify = FALSE)
引數列表:
- string: 字串,字串向量。
- pattern: 匹配字元。
- simplify: 返回值,TRUE返回matrix,FALSE返回字串向量
> val <- c("abca4", 123, "cba2")
# 返回匹配的數字
> str_extract(val, "\\d")
[1] "4" "1" "2"
# 返回匹配的字元
> str_extract(val, "[a-z]+")
[1] "abca" NA "cba"
> val <- c("abca4", 123, "cba2")
> str_extract_all(val, "\\d")
[[1]]
[1] "4"
[[2]]
[1] "1" "2" "3"
[[3]]
[1] "2"
> str_extract_all(val, "[a-z]+")
[[1]]
[1] "abca"
[[2]]
character(0)
[[3]]
[1] "cba"
3.4 字串變換函式
3.4.1 str_conv:字元編碼轉換
函式定義:
str_conv(string, encoding)
引數列表:
- string: 字串,字串向量。
- encoding: 編碼名。
對中文進行轉碼處理。
# 把中文字元位元組化
> x <- charToRaw('你好');x
[1] c4 e3 ba c3
# 預設win系統字符集為GBK,GB2312為GBK字集,轉碼正常
> str_conv(x, "GBK")
[1] "你好"
> str_conv(x, "GB2312")
[1] "你好"
# 轉UTF-8失敗
> str_conv(x, "UTF-8")
[1] "���"
Warning messages:
1: In stri_conv(string, encoding, "UTF-8") :
input data \xffffffc4 in current source encoding could not be converted to Unicode
2: In stri_conv(string, encoding, "UTF-8") :
input data \xffffffe3\xffffffba in current source encoding could not be converted to Unicode
3: In stri_conv(string, encoding, "UTF-8") :
input data \xffffffc3 in current source encoding could not be converted to Unicode
把unicode轉UTF-8
> x1 <- "\u5317\u4eac"
> str_conv(x1, "UTF-8")
[1] "北京"
3.4.2 str_to_upper,字串大寫轉換。
函式定義:
str_to_upper(string, locale = "")
str_to_lower(string, locale = "")
str_to_title(string, locale = "")
引數列表:
- string: 字串。
- locale:按哪種語言習慣排序
字串大寫轉換:
> val <- "I am conan. Welcome to my blog! http://fens.me"
# 全大寫
> str_to_upper(val)
[1] "I AM CONAN. WELCOME TO MY BLOG! HTTP://FENS.ME"
# 全小寫
> str_to_lower(val)
[1] "i am conan. welcome to my blog! http://fens.me"
# 首字母大寫
> str_to_title(val)
[1] "I Am Conan. Welcome To My Blog! Http://Fens.Me"
字串在平常的資料處理中經常用過,需要對字串進行分割、連線、轉換等操作,本篇中通過介紹stringr,靈活的字串處理庫,可以有效地提高程式碼的編寫效率。有了好的工具,在用R語言處理字串就順手了。