stringr には、大きく分けて4つの関数ファミリーがあります。
文字操作:これらの関数により、文字ベクトル内の文字列の個々の文字を操作することができます。
空白ツール:空白を追加、削除、操作するためのツールです。
ロケール依存の操作:操作はロケールによって異なります。
パターンマッチ機能。パターン記述の4つのエンジンを認識します。最も一般的なのは正規表現ですが、その他に3つのツールがあります。
文字列の長さは str_length()
で得ることができます。
str_length("abc")
#> [1] 3
これは、Rの基本関数 nchar()
と同等になりました。以前は、nchar()
の問題、例えば nchar(NA)
に対して 2 を返してしまうという問題を回避するために必要でした。これは R 3.3.0 の時点で修正されたので、もはやそれほど重要ではありません。
個々の文字にアクセスするには、 str_sub()
を使います。これは3つの引数を取ります: 文字ベクトル、 start
位置と end
位置です。前者は左から数えて正の整数か、後者は右から数えて負の整数になります。位置は文字列を含んでおり、文字列よりも長い場合は静かに切り捨てられます。
<- c("abcdef", "ghifjk")
x
# The 3rd letter
str_sub(x, 3, 3)
#> [1] "c" "i"
# The 2nd to 2nd-to-last character
str_sub(x, 2, -2)
#> [1] "bcde" "hifj"
また、文字列を修正するために str_sub()
を使用することができます。
str_sub(x, 3, 3) <- "X"
x#> [1] "abXdef" "ghXfjk"
個々の文字列を複製するには、str_dup()
を使用することができます。
str_dup(x, c(2, 3))
#> [1] "abXdefabXdef" "ghXfjkghXfjkghXfjk"
3つの関数が空白を追加、削除、修正します。
str_pad()
は、文字列の左側、右側、または両側に余分な空白を追加して、一定の長さになるようにパディングします。
<- c("abc", "defghi")
x str_pad(x, 10) # default pads on left
#> [1] " abc" " defghi"
str_pad(x, 10, "both")
#> [1] " abc " " defghi "
(引数 pad
を使えば、他の文字で埋めることができます)。
str_pad()
は決して文字列を短くすることはありません。
str_pad(x, 4)
#> [1] " abc" "defghi"
ですから、すべての文字列が同じ長さになるようにしたい場合(printメソッドでよく役に立ちます)、 str_pad()
と str_trunc()
を組み合わせてください。
<- c("Short", "This is a long string")
x
%>%
x str_trunc(10) %>%
str_pad(10, "right")
#> [1] "Short " "This is..."
str_pad()
の反対は str_trim()
で、これは先頭と末尾の空白を削除します。
<- c(" a ", "b ", " c")
x str_trim(x)
#> [1] "a" "b" "c"
str_trim(x, "left")
#> [1] "a " "b " "c"
str_wrap()
を使うと、段落のテキストを折り返すために既存の空白を修正し、各行の長さができるだけ同じになるようにすることができます。
<- str_c(
jabberwocky "`Twas brillig, and the slithy toves ",
"did gyre and gimble in the wabe: ",
"All mimsy were the borogoves, ",
"and the mome raths outgrabe. "
)cat(str_wrap(jabberwocky, width = 40))
#> `Twas brillig, and the slithy toves did
#> gyre and gimble in the wabe: All mimsy
#> were the borogoves, and the mome raths
#> outgrabe.
いくつかの stringr 関数は、ロケールに依存します:世界の異なる地域で異なる動作をします。これらの関数は大文字と小文字の変換を行う関数です。
<- "I like horses."
x str_to_upper(x)
#> [1] "I LIKE HORSES."
str_to_title(x)
#> [1] "I Like Horses."
str_to_lower(x)
#> [1] "i like horses."
# Turkish has two sorts of i: with and without the dot
str_to_lower(x, "tr")
#> [1] "ı like horses."
文字列の順序と並べ替え。
<- c("y", "i", "k")
x str_order(x)
#> [1] 2 3 1
str_sort(x)
#> [1] "i" "k" "y"
# In Lithuanian, y comes between i and k
str_sort(x, locale = "lt")
#> [1] "i" "y" "k"
ロケールのデフォルトは常に英語であり、システム間で同じ動作をするようにします。ロケールには、常に 2 文字の ISO-639-1 言語コード (英語なら “en” 、中国語なら “zh”) と、オプションで ISO-3166 国コード (en_UK" や “en_US” など) を指定することができます。利用可能なロケールの完全なリストは stringi::stri_locale_list()
を実行することで見ることができます。
stringr 関数の大半はパターンを使って動作します。これらの関数は、実行するタスクとマッチするパターンの種類によってパラメータ化されています。
各パターンマッチング関数の最初の2つの引数は同じで、処理する文字列の文字ベクトルとマッチする1つの pattern
です。stringr は文字列の detect, locate, extract, match, replace, split に対してパターンマッチング関数を提供します。ここでは、いくつかの文字列と、(米国の)電話番号にマッチするように設計された正規表現を用いて、これらの機能がどのように働くかを説明します。
<- c(
strings "apple",
"219 733 8965",
"329-293-8753",
"Work: 579-499-7527; Home: 543.355.3679"
)<- "([2-9][0-9]{2})[- .]([0-9]{3})[- .]([0-9]{4})" phone
str_detect()
はパターンの有無を検出し、論理ベクトルを返します(grepl()
と似ています)。str_subset()
は正規表現にマッチする文字ベクトルの要素を返します(grep()
で value = TRUE
とすることに似ているます)。
# Which strings contain phone numbers?
str_detect(strings, phone)
#> [1] FALSE TRUE TRUE TRUE
str_subset(strings, phone)
#> [1] "219 733 8965"
#> [2] "329-293-8753"
#> [3] "Work: 579-499-7527; Home: 543.355.3679"
str_count()
はマッチした数を数えます。
# How many phone numbers in each string?
str_count(strings, phone)
#> [1] 0 1 1 2
str_locate()
はパターンの 先頭 の位置を特定し、開始と終了の列を持つ数値行列を返します。str_locate_all()
は全てのマッチの位置を特定し、数値行列のリストを返します。regexpr()
と gregexpr()
に似ています。
# Where in the string is the phone number located?
<- str_locate(strings, phone))
(loc #> start end
#> [1,] NA NA
#> [2,] 1 12
#> [3,] 1 12
#> [4,] 7 18
str_locate_all(strings, phone)
#> [[1]]
#> start end
#>
#> [[2]]
#> start end
#> [1,] 1 12
#>
#> [[3]]
#> start end
#> [1,] 1 12
#>
#> [[4]]
#> start end
#> [1,] 7 18
#> [2,] 27 38
str_extract()
は 最初の マッチに対応するテキストを抽出し、文字ベクトルを返します。str_extract_all()
は全てのマッチを抽出し、文字ベクトルのリストを返します。
# What are the phone numbers?
str_extract(strings, phone)
#> [1] NA "219 733 8965" "329-293-8753" "579-499-7527"
str_extract_all(strings, phone)
#> [[1]]
#> character(0)
#>
#> [[2]]
#> [1] "219 733 8965"
#>
#> [[3]]
#> [1] "329-293-8753"
#>
#> [[4]]
#> [1] "579-499-7527" "543.355.3679"
str_extract_all(strings, phone, simplify = TRUE)
#> [,1] [,2]
#> [1,] "" ""
#> [2,] "219 733 8965" ""
#> [3,] "329-293-8753" ""
#> [4,] "579-499-7527" "543.355.3679"
str_match()
は 最初の マッチから ()
で形成されるキャプチャグループを抽出します。 これは、完全なマッチを表す1列と、各グループを表す1列からなる文字行列を返します。str_match_all()
は全てのマッチからキャプチャグループを抽出し、文字列行列のリストを返します。regmatches()
に似ています。
# Pull out the three components of the match
str_match(strings, phone)
#> [,1] [,2] [,3] [,4]
#> [1,] NA NA NA NA
#> [2,] "219 733 8965" "219" "733" "8965"
#> [3,] "329-293-8753" "329" "293" "8753"
#> [4,] "579-499-7527" "579" "499" "7527"
str_match_all(strings, phone)
#> [[1]]
#> [,1] [,2] [,3] [,4]
#>
#> [[2]]
#> [,1] [,2] [,3] [,4]
#> [1,] "219 733 8965" "219" "733" "8965"
#>
#> [[3]]
#> [,1] [,2] [,3] [,4]
#> [1,] "329-293-8753" "329" "293" "8753"
#>
#> [[4]]
#> [,1] [,2] [,3] [,4]
#> [1,] "579-499-7527" "579" "499" "7527"
#> [2,] "543.355.3679" "543" "355" "3679"
str_replace()
は **最初にマッチしたパターンを置換し、文字ベクトルを返します。str_replace_all()
はマッチした全てのパターンを置き換えます。sub()や
gsub()` に似ています。
str_replace(strings, phone, "XXX-XXX-XXXX")
#> [1] "apple"
#> [2] "XXX-XXX-XXXX"
#> [3] "XXX-XXX-XXXX"
#> [4] "Work: XXX-XXX-XXXX; Home: 543.355.3679"
str_replace_all(strings, phone, "XXX-XXX-XXXX")
#> [1] "apple"
#> [2] "XXX-XXX-XXXX"
#> [3] "XXX-XXX-XXXX"
#> [4] "Work: XXX-XXX-XXXX; Home: XXX-XXX-XXXX"
str_split_fixed()
は文字列をパターンに基づいて 固定 個に分割し、文字列行列を返します。str_split()
は文字列を 可変 個の断片に分割し、文字ベクトルのリストを返す。
str_split("a-b-c", "-")
#> [[1]]
#> [1] "a" "b" "c"
str_split_fixed("a-b-c", "-", n = 2)
#> [,1] [,2]
#> [1,] "a" "b-c"
stringr がパターンを記述するために使用できる主なエンジンは4つあります。
正規表現は、上に示したようにデフォルトです。 vignette("regular-expressions")
fixed()
によるバイトワイズ固定マッチング。
局所的な文字マッチング、 coll()
を使用します。
boundary()
によるテキスト境界の解析。
fixed(x)
は x
で指定されたバイト列と正確にマッチするだけです。これは非常に限定された「パターン」ですが、この制限によってマッチングをより高速に行うことができます。英語以外のデータで fixed()
を使用することに注意してください。同じ文字を表現するのに複数の方法があることが多いので、問題があります。例えば、“á” を定義する場合、一文字として定義する方法と、“a” にアクセントを加えたものとして定義する方法の二通りがあります。
<- "\u00e1"
a1 <- "a\u0301"
a2 c(a1, a2)
#> [1] "á" "á"
== a2
a1 #> [1] FALSE
これらは同じようにレンダリングされますが、定義が異なるため、 fixed()
はマッチを見つけることができません。代わりに、以下に説明する coll()
を使用すると、人間の文字比較ルールを尊重することができます。
str_detect(a1, fixed(a2))
#> [1] FALSE
str_detect(a1, coll(a2))
#> [1] TRUE
coll(x)
は人間の言語による collation ルールを使って x
にマッチするものを探します。大文字小文字を区別しないマッチングを行いたい場合には特に重要です。照合順序のルールは世界中で異なるので、 locale
パラメータを指定する必要があります。
<- c("I", "İ", "i", "ı")
i
i#> [1] "I" "İ" "i" "ı"
str_subset(i, coll("i", ignore_case = TRUE))
#> [1] "I" "i"
str_subset(i, coll("i", ignore_case = TRUE, locale = "tr"))
#> [1] "İ" "i"
coll()
の欠点は速度です。どの文字が同じであるかを認識するルールが複雑なため、 coll()
は regex()
や fixed()
に比べて相対的に遅くなります。なお、 fixed()
と regex()
の両方が ignore_case
引数を持つ場合は、 coll()
よりもずっと単純な比較を行います。
boundary()
は、文字、行、文、単語の間の境界をマッチさせます。これは str_split()
と一緒に使うと便利ですが、すべてのパターンマッチング関数と一緒に使うことができます。
<- "This is a sentence."
x str_split(x, boundary("word"))
#> [[1]]
#> [1] "This" "is" "a" "sentence"
str_count(x, boundary("word"))
#> [1] 4
str_extract_all(x, boundary("word"))
#> [[1]]
#> [1] "This" "is" "a" "sentence"
慣例により、""
は boundary("character")
として扱われます。
str_split(x, "")
#> [[1]]
#> [1] "T" "h" "i" "s" " " "i" "s" " " "a" " " "s" "e" "n" "t" "e" "n" "c" "e" "."
str_count(x, "")
#> [1] 19