Rで文字列操作を行う際に、標準パッケージ(base
パッケージ)やstringr
パッケージを使っていることが多いと思う。
私の周囲にはstringr
を好む人が多いけれども、実際、どちらを使った方がよいのか、調べてみた。
R標準パッケージ、stringrパッケージの比較
標準パッケージ (base R
)
メリット
- 追加インストールが不要:どの環境でもすぐに使用可能。
- 小規模データでは、実行速度が速い:
gsub()
やgrep()
などは軽量で高速。 - 単純な作業には十分:ちょっとした文字列の置換や抽出には便利。
主な関数
nchar()
:文字数のカウントsubstr()
:文字列の一部を抽出grep()
/grepl()
:パターンマッチング(ベクター内の検索)gsub()
:文字列の置換paste()
/paste0()
:文字列の結合strsplit()
:文字列の分割
使用例
# 文字数カウント
nchar("こんにちは")
# 文字の置換
gsub("a", "A", "banana")
# 文字の抽出
substr("banana", 2, 4)
# 文字の結合
paste("Hello", "World", sep = ", ")
# パターン検索
grepl("R", c("Python", "R", "Julia"))
output
result: 5
result: "bAnana"
result: "ana"
result: "Hello, World"
result: FALSE, TRUE, FALSE
stringr
パッケージ
メリット
- 大規模データでの処理速度が速い。
- 関数名が直感的:
str_
から始まる関数が統一されているため、覚えやすい。 - デフォルトの動作がわかりやすい:「第一引数が対象文字列、第二引数がパターン」で統一。
- 関数がベクトル化されている:ベクトルに対しても簡単に使える。
factor
とcharacter
を同じように扱う。- tidyverseの一部:tidyverseを使う場合、
dplyr
などとシームレスに連携可能。 - 引数オブジェクトの各要素の名前や位置を保持する。
- 長さゼロのオブジェクトを引数として与えた場合には長さゼロの結果を返す。
- 引数オブジェクトに
NA
が含まれる場合はその部分の結果をNA
とする。
主な関数
str_length()
:文字数のカウント(nchar()
の代替)str_sub()
:文字列の部分抽出(substr()
の代替)str_replace()
:文字の置換(gsub()
の代替)str_detect()
:パターン検出(grepl()
の代替)str_c()
:文字列の結合(paste0()
の代替)str_split()
:文字列の分割(strsplit()
の代替)
使用例
# stringrパッケージの読み込み
library(stringr)
# 文字数カウント
str_length("こんにちは")
# 文字の置換
str_replace("banana", "a", "A")
# すべての一致箇所を置換
str_replace_all("banana", "a", "A")
# 文字の抽出
str_sub("banana", 2, 4)
# 文字の結合
str_c("Hello", "World", sep = ", ")
# パターン検索
str_detect(c("Python", "R", "Julia"), "R")
output
result: 5
result: "bAnAnA"
result: "bAnAnA"
result: "ana"
result: "Hello, World"
選び方のポイント
baseとstringrのどちらが有利か、条件毎にまとめるとこんな感じ。
基準 | base R (標準)関数 |
stringr (外部パッケージ) |
---|---|---|
可読性 | ✕ 難しい (gsub , substr ) |
〇 わかりやすい (str_replace , str_sub ) |
直感的な名前 | ✕ 不統一 (gsub , paste0 ) |
〇 統一的 (str_ で始まる) |
シンプルな作業 | 〇 十分対応可能 | 〇 十分対応可能 |
複雑な作業 | ✕ 面倒、正規表現が複雑 | 〇 簡単で分かりやすい |
追加インストール | 〇 不要 | ✕ 必要(install.packages("stringr") ) |
関数の速度 | 〇 高速 | ✕ やや遅い(大規模データではbaseが有利) |
実際、どちらを使うべき?
具体的な場面を想定すると、こんな感じ。
作業の種類 | 有利な方 | 理由 |
---|---|---|
単純な置換 | gsub() (base) |
速くて簡単。シンプルな作業に最適 |
パターンマッチング | str_detect() |
grepl() より直感的で見やすい |
ベクトルの操作 | stringr |
ベクトルの操作が簡単 |
繰り返しの抽出 | stringr |
str_extract_all() が便利 |
コードの可読性 | stringr |
統一された関数名でわかりやすい |
大規模データ | base R |
大きなデータではgsub() が速い |
まとめ
- 可読性や一貫性を重視するなら
stringr
。- 直感的な名前 (
str_replace
,str_length
など) でコードが読みやすい。 tidyverse
パッケージを使うならstringr
が便利。- 大規模データでは、
stringr
の方がbaseよりも処理速度が速いことがある。
- 直感的な名前 (
- 速度や標準機能で十分な場合は
base R
を使うと良い。- シンプルな置換 (
gsub()
) や正規表現 (grep()
,grepl()
) は速い。 - 追加インストールが不要で、どの環境でも使える。
- シンプルな置換 (
速度について具体的に比較した記事はこちら。
前回、R標準パッケージ(base)とstringrパッケージの比較をしてみて、「処理速度は、場合によってはbase、場合によってはstringrの方が速い」ということがわかった。 で、具体的にどのときにbase、どのとき …
実際に使うときは、
「Tidyverseのワークフロー(dplyr
, ggplot2
など)を使うなら、stringr
を使ったほうが可読性が高いけど、シンプルな文字列処理やパフォーマンスが重要な場合は、base
関数のgsub()
, paste()
, nchar()
の方が有利」
とゆー感じかな。
他の人たちはどれくらい使い分けているんだろう。。。