1. 程式人生 > >stringr包字元處理函式簡介

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。

目錄

  1. stringr介紹
  2. stringr安裝
  3. 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")

# 把目標字串第一個出現的ab,替換為-
> str_replace(val, "[ab]", "-")
[1] "-bc" "123" "c-a"

# 把目標字串所有出現的ab,替換為-
> 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

# 匹配ab字元,以字串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語言處理字串就順手了。