文字列を部分的に抽出したり、置換したりするときには、R標準パッケージ(base)のsubstr()
、もしくは stringrパッケージならstr_sub()
を使う。
substr()
は、Rの標準関数で、インストール不要でどこでも使える。str_sub()
は、stringrパッケージの関数で、可読性が高く、機能が充実。
現実的には、以下のような理由から、後述のstr_sub()
を使うことが多い。
- 部分文字列の抽出:
str_sub()
が圧倒的に便利で直感的。 - 文字の置換:
str_sub()
だけが可能(substr()
では無理)。 - 負のインデックス(文字列の末尾からの指定):
str_sub()
だけが対応。 - substr()は、シンプルな文字列の部分抽出に適しているけれど、機能はやや限定的。
……なので、ここでは str_sub()
の方から書き留めておく。
str_sub()
str_sub()
は、stringr
パッケージの関数で、より直感的で使いやすい関数。
私は日頃、こちらの方をよく使っている。
負のインデックス、ベクトル処理、文字列の置換が非常に柔軟に行えるのが特徴。
str_sub()は、stringerパッケージに含まれている関数なので、まずはパッケージをインストール&読み込む必要がある。
# stringrパッケージのインストール
install.packages("stringr")
# stringrパッケージの読み込み
library(stringr)
str_sub(x, start, end)
x
: 文字列または文字ベクトルstart
: 開始位置(1から始まるインデックス または 負のインデックス)end
: 終了位置(1から始まるインデックス または 負のインデックス)
使い方の例
文字列の部分抽出
text <- "Hello, World!"
# 1文字目から5文字目を抽出
result <- str_sub(text, 1, 5)
print(result)
output
[1] "Hello"
負のインデックスを使った抽出
# 末尾から5文字を抽出
result <- str_sub(text, -6, -1)
print(result)
output
[1] "World!"
- 負のインデックス(-6, -1)で、末尾からの文字抽出が可能。
- substr()ではできなかった操作が可能になる。
文字の置換
text <- "Hello, World!"
# 1文字目から5文字目を "Hi!!" に置換
str_sub(text, 1, 5) <- "Hi!!"
print(text)
output
[1] "Hi!!o, World!"
- 部分置換が簡単にできる。
substr()
と同様の置換ですが、可読性が高いのがポイント。
ベクトルへの対応
texts <- c("Hello", "World", "Programming")
# 1文字目から3文字目を抽出
result <- str_sub(texts, 1, 3)
print(result)
output
[1] "Hel" "Wor" "Pro"
- ベクトルを一度に処理するのが
str_sub()
の強み。
NAの処理
texts <- c("Hello", NA, "World")
# 1文字目から3文字目を抽出
result <- str_sub(texts, 1, 3)
print(result)
output
[1] "Hel" NA "Wor"
- NAはそのままNAとして返される。
str_sub() のまとめ
str_sub() の使い方をざっくりとまとめると、以下のような感じ。
操作 | コード例 | 結果 |
---|---|---|
部分抽出 | str_sub("Hello", 1, 3) |
"Hel" |
ベクトル対応 | str_sub(c("Hello", "World"), 1, 3) |
"Hel", "Wor" |
負のインデックス | str_sub("Hello", -3, -1) |
"llo" |
置換 | str_sub(text, 1, 5) <- "Hi!!" |
"Hi!!o, World!" |
NAの処理 | str_sub(c("Hello", NA), 1, 3) |
"Hel", NA |
substr()
substr
は、Rの標準関数 (base R) で、文字列の一部分を抽出・変更するために使用する。
シンプルな文字列の部分抽出に適しているけれど、機能はやや限定的。
substr(x, start, stop)
x
: 文字列または文字ベクトルstart
: 抽出を開始する位置(1から始まるインデックス)stop
: 抽出を終了する位置(stop位置の文字も含む)
- stopは、前からしか数えられないのが残念なところ(後述のstr_subは後ろからも数えられる)。
使い方の例
文字列の部分抽出
text <- "Hello, World!"
# 1文字目から5文字目を抽出
result <- substr(text, 1, 5)
print(result)
output
[1] "Hello"
- 1から5番目の文字を抽出した。
複数の文字列の部分抽出
texts <- c("Hello", "World", "Programming")
# 各要素の1文字目から3文字目を抽出
result <- substr(texts, 1, 3)
print(result)
output
[1] "Hel" "Wor" "Pro"
- 3つの要素があるベクトルに対して、各要素の1文字目から3文字目を抽出した。
部分文字列の置換
substr()
は、部分文字列を置換するための左辺代入も可能。
text <- "Hello, World!"
# 1文字目から5文字目を "Hi!!" に置換
substr(text, 1, 5) <- "Hi!!"
print(text)
output
[1] "Hi!!o, World!"
- 1から5番目の文字がHi!!に置換された。
- 文字数が異なっても置換は可能(置換後の文字数が変更される)。
NAの処理
texts <- c("Hello", NA, "World")
# 1文字目から3文字目を抽出
result <- substr(texts, 1, 3)
print(result)
output
[1] "Hel" NA "Wor"
- NAはそのままNAとして返される。
空文字の処理
text <- ""
# 1文字目から3文字目を抽出
result <- substr(text, 1, 3)
print(result)
output
[1] ""
- 空文字列の部分抽出を行うと、空文字のまま返される。
substr() のまとめと注意点
substr() の使い方をざっくりとまとめると、以下のような感じ。
操作 | コード例 | 結果 |
---|---|---|
部分抽出 | substr("Hello", 1, 3) |
"Hel" |
ベクトル対応 | substr(c("Hello", "World"), 1, 3) |
"Hel", "Wor" |
置換 | substr(text, 1, 5) <- "Hi!!" |
"Hi!!o, World!" |
NAの処理 | substr(c("Hello", NA), 1, 3) |
"Hel", NA |
負のインデックス | 使えない | - |
-
負のインデックスは使えない
- Rの
substr()
は、負のインデックス(末尾からの抽出)には対応していない。 - 例:
substr("Hello", -3, -1)
はエラーになる。
- Rの
-
置換する際は、左辺代入が必要
- 文字を置換する際は、
substr(text, start, stop) <- "新しい文字列"
という構文を使う。
- 文字を置換する際は、
substr() と str_sub() の比較
substr()とstr_sub()の違いをまとめると、以下のようになる。
やりたいこと | str_sub() | substr() | おすすめ |
---|---|---|---|
文字の部分抽出 | ✅ 可能(おすすめ) | ✅ 可能 | ✅ str_sub() |
文字の部分置換 | ✅ 簡単に置換が可能 | ⚠️ 一部可能 (代入式が必要) | ✅ str_sub() |
ベクトルへの適用 | ✅ ベクトル化されている | ⚠️ 制限あり | ✅ str_sub() |
末尾からの指定 | ✅ 負のインデックスが使える | ❌ 不可 | ✅ str_sub() |
使いやすさ | ✅ わかりやすい構文 | ⚠️ やや使いにくい | ✅ str_sub() |
パッケージ | stringr (追加) | base R (標準) | - |
どっちを使うべき?
イメージとしては、「ほとんどの場面ではstr_sub()
が良いけど、ただし、シンプルな部分抽出だけならsubstr()
でも問題ない」といった感じ。
状況 | おすすめの関数 | 理由 |
---|---|---|
シンプルな部分抽出 | substr() |
Rの標準関数のため手軽に使える |
置換が必要な場合 | str_sub() |
直接的に置換が可能で便利 |
末尾からの操作が必要 | str_sub() |
負のインデックスが使える |
ベクトルの処理が必要 | str_sub() |
ベクトル化されているので効率的 |