やりたいこと
データ分析の際に、文字列の先頭から決まった文字数だけ削りたいということがある。例えば、"AS101", "BD2372A", "7G66B"
といった文字列の先頭から2文字分だけ削って、"101", "2372A", "66B"
としたいことがある。
あるいは、文字列の末尾から決まった文字数だけ削りたいということがある。例えば、"福岡県知事", "神奈川県知事", "東京都知事", "大阪府知事"
のそれぞれ末尾の3文字を削って、"福岡", "神奈川", "東京", "大阪"
という文字列を得たいことがある。
このように文字列の先頭や末尾を削りたい場合、部分文字列を取り出すという手法が使える。
先頭の2文字を削りたければ、先頭から数えて3文字目から末尾までの部分文字列を取り出せばよい。また、末尾の3文字を削りたければ、先頭から始めて、末尾から数えて4文字目までの部分文字列を取り出せばよい。
stringr
パッケージで部分文字列を取り出す
部分文字列を取り出す場合、stringr
パッケージの str_sub
という函数を使う。str_sub
函数は、str_sub(string, start, end)
という形で、3つの引数を取る。
string
: 入力として与えられる文字列ベクトルstart
: 部分文字列が始まる位置end
: 部分文字列が終わる位置
始まる位置と終わる位置は、整数で指定する。例えば、5文字目から8文字目までならば、str_sub(string, start = 5, end = 8)
とすればよい。
末尾から数えた場合の位置
今の例では、正の整数で位置を指定したが、負の整数で位置を指定することもできる。負の整数を使うと、末尾から数えた場合の位置を指定することができる。
例えば、「さしすせそ」という5文字から成り立つ文字列を考えよう。ここで「せ」は末尾から数えて2文字目の位置にあるので、負の整数を使えば、-2という形で位置を指定することができる。もちろん、「せ」は先頭から数えて4文字目の位置にあるので、正の整数を用いて、4という形で位置を指定することはできる。
この「さしすせそ」の例で、正の整数を使って先頭から数える場合と、負の正を使って末尾から数える場合についてまとめると以下のようになる。
文字列 | さ | し | す | せ | そ |
---|---|---|---|---|---|
先頭から数える | 1 | 2 | 3 | 4 | 5 |
末尾から数える | -5 | -4 | -3 | -2 | -1 |
ついでに、もう1つ例を見てみよう。
文字列 | い | ろ | は | に | ほ | へ | と |
---|---|---|---|---|---|---|---|
先頭から数える | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
末尾から数える | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
だから、末尾から数えて7文字目より始めて、末尾から数えて3文字目で終わるような部分文字列を取り出したければ、str_sub(string, start = -7, end = -3)
とすればよい。
なお、正の整数による位置指定と負の整数による位置指定は混在していてもかまわない。例えば、先頭から数えて6文字目より始めて、末尾から数えて2文字目で終わるような部分文字列は、str_sub(string, start = 6, end = -2)
で取り出すことができる。
先頭から決まった文字数だけ削る
それでは、ここまでのことを踏まえて、先頭から決まった文字数だけ削る方法について説明しよう。
例えば、先頭の2文字分を削りたいとする。先頭の2文字分だけを削るということは、先頭から数えて3文字目より始めて、末尾から数えて1文字目 [1] で終わるような部分文字列を得ることと同じである。このことをRの函数で表現すれば、str_sub(string, start = 3, end = -1)
となる [2] 。
ただし、str_sub
函数では、引数 end
のデフォルト値が-1とされている。このため、end = -1
と書かなくても、end = -1
と書いたことと同じになる。よって、単に str_sub(string, start = 3)
と書くだけで、先頭の2文字分だけを削ったものを得ることができる。
ちょっとした例を以下に掲げておこう。
library("stringr") x <- c("AS101", "BD2372A", "7G66B") str_sub(x, start = 3) # 結果は "101" "2372A" "66B"
末尾から決まった文字数だけ削る
末尾から決まった文字数だけ削る場合も似たような形でできる。
例えば、末尾の3文字だけ削りたいとする。この場合、先頭から数えて1文字目 [3] より始めて、末尾から数えて4文字目で終わるような部分文字列を得ればよい。Rの函数で表現すれば str_sub(string, start = 1, end = -4)
となるが、引数 start
のデフォルト値は1とされているので、引数 start
を省略して str_sub(string, end = -4)
とするだけで末尾の3文字だけを削ることができる。
例を以下に掲げておこう。
library("stringr") x <- c("福岡県知事", "神奈川県知事", "東京都知事", "大阪府知事") str_sub(x, end = -4) # 結果は"福岡" "神奈川" "東京" "大阪"
別解:substr
函数を使う
Rの base
パッケージに入っている substr
函数でも部分文字列を取り出すことができる。ただ、これは stringr
パッケージの str_sub
函数ほど使い勝手がよくない。
まず、substr
函数は、負の数を使って位置を指定することができない。さらに、str_sub
函数のようなデフォルト値の設定がない。このため、substr
函数を使うとどうしても冗長になってしまう。
例えば、末尾の3文字だけを削りたければ、substr(string, start = 1, stop = nchar(string)-3)
としなくてはならない。なお、ここで nchar(string)
は string
の文字数を返す函数である。
別解:正規表現を使って置換する
正規表現を使って、先頭から決まった文字数をマッチさせることができる。また、末尾から決まった文字数をマッチさせることもできる。こうしてマッチしたものを空の文字列に置換することで、削ることができる。ただし、与える文字列が短すぎる場合、正規表現による置換の方法と、部分文字列を使った方法とでは結果に違いが生じる。
とりあえず、先頭の2文字を削る例を以下に挙げる。^.{2}
というのが先頭の2文字にマッチさせるための正規表現である。^
が先頭を示し、.{2}
が任意の2文字を示している。
x <- c("AS101", "BD2372A", "7G66B") gsub("^.{2}", "", x) # 結果は "101" "2372A" "66B"
また、以下は末尾の3文字を削る例である。.{3}$
というのが末尾の3文字にマッチさせるための正規表現である。.{3}
が任意の3文字を示し、$
が末尾を示している。
x <- c("福岡県知事", "神奈川県知事", "東京都知事", "大阪府知事") gsub(".{3}$", "", x) # 結果は"福岡" "神奈川" "東京" "大阪"
なお、gsub
の代わりに strigr
パッケージの函数を使いたければ、str_replace_all(x, ".{3}$", "")
とすればよい。
与える文字列が短すぎる場合
先ほど、与える文字列が短すぎる場合は、正規表現による置換の方法と、部分文字列を使った方法とで違いが出ると述べた。
例えば、末尾の3文字を削りたいのに、そもそも文字列が2文字しかないようなときに違いが出てくる。
library("stringr") y <- "市長" str_sub(y, end = -4) # 結果は "" gsub(".{3}$", "", y) # 結果は "市長"
部分文字列の str_sub
を使う方法では、文字を削りきって1文字もないもの(=空文字列)が返る。これに対して、置換の gsub
を使う方法では、そもそも「末尾の3文字」(.{3}$
) にマッチしないので、置換が行われず、入力がそのまま返ることになる。