stringrを使って文字列処理をやってみる

SappoRo.R #7

前田和寛(@kazutan)

2016/10/29

stringr

文字列を操作するパッケージ

  • stringiパッケージのwrapper
    • 元は違ったけど“i”の性能がよかったから
    • Hadley Wickham謹製
  • 特徴
    • baseの関数群より処理が速い
    • 関数名が“str_”で始まってる
    • 主な文字列処理はこれひとつでOK
    • “%>%”で連鎖しやすい!

インストール

CRANからインストール

install.packages("stringr")

GitHubからインストール

devtools::install_github("hadley/stringr")

githubinstallでもOK

githubinstall::githubinstall("stringr")

参考資料

加工

文字列の連結 str_c()

str_c("kosaki", "love", sep = " ")
## [1] "kosaki love"
  • 文字列を連結させる
  • paste()と同じように使える
x <- c("kosaki", "chitoge", "marika")
str_c(x, collapse = ", ")
## [1] "kosaki, chitoge, marika"
  • 文字列ベクトルの要素をひとつに連結させるにはcollapse=オプションを使用
  • このあたりもpaste()と同様
y <- c("love", "like", "like")
(ni <- str_c(x, y, sep="-"))
## [1] "kosaki-love"  "chitoge-like" "marika-like"
  • 文字列ベクトル同士を引っ付けることも可能

文字列の分割: str_split()

str_split(ni, pattern = "-")
## [[1]]
## [1] "kosaki" "love"  
## 
## [[2]]
## [1] "chitoge" "like"   
## 
## [[3]]
## [1] "marika" "like"
  • パターンに一致したところで分割
  • 返り値はリスト型がデフォルト
str_split(ni, pattern = "-", simplify = TRUE)
##      [,1]      [,2]  
## [1,] "kosaki"  "love"
## [2,] "chitoge" "like"
## [3,] "marika"  "like"
  • simplify=TRUEで行列型で返す
str_split("k-o-s-a-k=i", pattern = "-", n=3)
## [[1]]
## [1] "k"       "o"       "s-a-k=i"
  • n=オプションで,分割数を指定することも可能
  • この時どこで区切られるかは,先頭優先となります

文字列の分割: str_split_fixed()

a <- c("kosaki-love","chitoge-like","tugumi")
str_split_fixed(a, pattern="-", n=2)
##      [,1]      [,2]  
## [1,] "kosaki"  "love"
## [2,] "chitoge" "like"
## [3,] "tugumi"  ""
  • str_split()同様,文字列を分割
  • ただし区切る場所がない場合,長さ0の文字列が入ります

検索

文字を含むかどうか(論理値): str_detect()

x <- c("kosaki", "chitoge", "marika")
str_detect(x, pattern="ko")
## [1]  TRUE FALSE FALSE
  • ベクトル内で,パターンにマッチした文字があるかどうかを判定
  • 返り値は論理ベクトル
str_detect(x,pattern="a$")
## [1] FALSE FALSE  TRUE
  • パターンに正規表現を使用することも可能

文字を含むかどうか(要素): str_subset()

str_subset(x, pattern="o")
## [1] "kosaki"  "chitoge"
  • ベクトル内で,パターンにマッチした文字があるかどうかを判定
  • 返り値は,マッチした要素のみの文字列ベクトル

置換

文字列の置換(先頭一致): str_replase()

str_replace(x, pattern="k", replacement="*")
## [1] "*osaki"  "chitoge" "mari*a"
  • パターンにマッチした文字列を置換
  • 要素内に複数マッチした場合,先頭のみを置換

文字列の置換(全部): str_replase_all()

str_replace_all(x, pattern="k", replacement="*")
## [1] "*osa*i"  "chitoge" "mari*a"
  • パターンにマッチした文字列を置換
  • 要素内に複数マッチした場合,すべて置換

抽出

マッチした要素を抽出: str_extract()

str_extract(x, pattern="ko")
## [1] "ko" NA   NA
  • パターンにマッチした箇所だけを取り出す
  • 返り値はベクトル
  • 先頭一致(要素内で他にも該当する場所があっても無視)

マッチした要素をすべて抽出: str_extract_all()

str_extract_all(x, pattern="k|s", simplify=TRUE)
##      [,1] [,2] [,3]
## [1,] "k"  "s"  "k" 
## [2,] ""   ""   ""  
## [3,] "k"  ""   ""
  • パターンにマッチした箇所すべてを取り出す
  • 返り値はデフォルトでリスト
    • simplify=TRUEで行列に

数値で指定して抽出: str_sub()

str_sub(x, start=1, end=4)
## [1] "kosa" "chit" "mari"
str_sub(x, start=4, end=-1)
## [1] "aki"  "toge" "ika"
  • startで開始位置、endで終了位置を指定
  • マイナスを指定すると後ろからの位置を指定

その他

文字のエンコーディング: str_conv()

str_conv(x, encoding="UTF-8")
  • 文字コードを変換させる
  • iconv()と同じようなもの

正規表現のViewer: str_view()

str_view(x, "a$")
  • 正規表現でのマッチ結果をRStudioのViewerに出してくれる
  • 最近組み込まれた
  • 正規表現の練習にも使えるし便利

以下省略

  • 文字列の抽出(グループ): str_match()
  • 条件を含んだ箇所のカウント: str_count()
  • パターンの位置: str_locate()
  • 文字列の長さ: str_length()
  • 文字列の繰り返し: str_dup()
  • などなど

実用例

Webスクレイピング

  • スクレイピングする対象を絞るとき
  • スクレイピングして取得したデータを前処理するとき

  • 台風22号と23号
    • スクレイピングして取得したデータを整形
    • パイプ演算子使えるの超助かった

レコードの抽出

  • データセットで,正規表現による部分一致でレコードを抽出するときなど
tibble::rownames_to_column(mtcars, var = "name") %>% 
  dplyr::filter(str_detect(.$name, "Mazda"))
##            name mpg cyl disp  hp drat    wt  qsec vs am gear carb
## 1     Mazda RX4  21   6  160 110  3.9 2.620 16.46  0  1    4    4
## 2 Mazda RX4 Wag  21   6  160 110  3.9 2.875 17.02  0  1    4    4

Enjoy!

今日の資料置き場 - https://kazutan.github.io/SappoRoR7