Rで解析:文字列操作と検索「grep」と置換「gsub」コマンドや正規表現の紹介

Rの解析に役に立つ記事
スポンサーリンク

文字列操作のコマンドと文字列をパターン(キーワード)で検索する”grepコマンド”と置換する”gsubコマンド”を紹介します。正規表現での抽出も簡単に紹介します。

grepコマンドを使うことでデータの項目名などで繰り返しの処理ができます。
Rとウェブ解析:データフレームの項目名で処理を繰り返す

文字の置換に役に立つかもしれない記事の紹介です。
・Rで解析:文字操作が楽々「stringr」パッケージ
https://www.karada-good.net/analyticsr/r-640

コマンドはR version 4.2.3で確認しています。

スポンサーリンク

文字列の置き換えなどのコマンド

空白を含む文字数のカウント、空白の削除、文字列の置き換え、文字列の切り出しに関するコマンドです。

#文字列の例、半角空白含めて16文字
# KARADANI EMONO 
Test <- " KARADANI EMONO "

#文字数を確認
nchar(Test)
[1] 16

#半角空白を全て除く
gsub(" ", "", Test)
[1] "KARADANIEMONO"

#先頭の半角空白を除く
gsub("^ ", "", " KARADANI EMONO ")
[1] "KARADANI EMONO "

#最後尾の半角空白を除く
gsub(" $", "", " KARADANI EMONO ")
[1] " KARADANI EMONO"

#文字列から一部を取り出す
#4から11文字までを取り出す
substring(Test, 4, 11)
[1] "RADANI E"

#文字列の5と6文字目をXXに置き換える
substring(Test, 5, 6) <- "XX"
#置換前
[1] " KARADANI EMONO "
#置換後
Test
[1] " KARXXANI EMONO "

#空白を含む文字列を指定の長さで切り出す
strtrim(Test, 9)
[1] " KARADANI"

#文字を指定した内容で分割
#文字Aで分割
#指定した文字は消えてしまします
#結果はlistなのでunlistでベクトルにしています。
unlist(strsplit(Test, "A"))
[1] " K"        "R"         "D"         "NI EMONO "

文字列の結合などのコマンド

文字列の結合、文字列ベクトルの作成、文字列の数字化などのコマンド

###文字列の結合コマンド:paste#####
#文字列例の作成
Text1 <- c("KARADA1", "KARADA2")
Text2 <- " NI "
Text3 <- "EMONO"

#各文字列の最後尾に半角空白が挿入され結合されます
paste(Text1, Text2, Text3)
[1] "KARADA1  NI  EMONO" "KARADA2  NI  EMONO"

#sepオプション""で空白を挿入せずに結合
paste(Text1, Text2, Text3, sep = "")
[1] "KARADA1 NI EMONO" "KARADA2 NI EMONO"

#collapseオプションは指定した文字列で
#文字列を結合して単一の文字列を作成します
paste(Text1, Text2, Text3, sep = "", collapse = " ? ")
[1] "KARADA1 NI EMONO ? KARADA2 NI EMONO"

#オプションが「sep = ""」専用のコマンド:paste0
#空白を挿入せずに結合
paste0(Text1, Text2, Text3)
[1] "KARADA NI EMONO"
########

#文字列ベクトルの作成
TsetChar <- character(10)
TsetChar
[1] "" "" "" "" "" "" "" "" "" ""
class(TsetChar)
[1] "character"

#文字列への変換
class(10)
[1] "numeric"
class(as.character(10))
[1] "character"

###数字の文字列を数字に変換:type.convertコマンド#####
Text1 <- "1"
Text2 <- "2"

#エラーが起きます
Text1 + Text2
Error in Text1 + Text2 : non-numeric argument to binary operator

#type.convertの使用
type.convert(Text1, as.is = TRUE) + type.convert(Text2, as.is = TRUE)
[1] 3
########

#アルファベットを出力する関数
#大文字
LETTERS[1:7]
[1] "A" "B" "C" "D" "E" "F" "G"
#小文字
letters[10:16]
[1] "j" "k" "l" "m" "n" "o" "p"

検索する”grepコマンド”と置換する”gsubコマンド”

内容はコメントを確認してください。

#からだにいいものタイトル
Test <- c("Rで解析:フォルダのコピーや作成など「pathological」パッケージの紹介とパッケージに依存しない方法",
          "Rのガイド:研究者も、社会人も、おねえさんも。とりあえず、みんなで使ってみませんか?",
          "Rで解析:画像のカラーコードを取得する方法!「EBImage」パッケージの紹介",
          "Rでお遊び:プレゼン資料の配色に使えるかも?キャラクターの髪の色?")

###grepはキーワードを含む文字列の位置を出力#####
#紹介を含むタイトルの順位
grep("紹介", Test)
[1] 1 3

#grepを利用した文字列の抽出方法
#文字列にガイドを含むタイトルを抽出
Test[grep("ガイド", Test)]
[1] "Rのガイド:研究者も、社会人も、おねえさんも。とりあえず、みんなで使ってみませんか?"

#複数のキーワードも設定できます
#例はor"|"です
Test[grep("おねえさん|髪", Test)]
[1] "Rのガイド:研究者も、社会人も、おねえさんも。とりあえず、みんなで使ってみませんか?"
[2] "Rでお遊び:プレゼン資料の配色に使えるかも?キャラクターの髪の色?" 

#正規表現も使えます
#先頭(^)に"Rの"の文字を含むタイトル
Test[grep("^Rの", Test)]
[1] "Rのガイド:研究者も、社会人も、おねえさんも。とりあえず、みんなで使ってみませんか?"
########

###gsubは対象キーワードに該当する文字列を指定内容で置換します#####
#gsub(対象キーワード, 指定内容, 文字列)
#おねえさんをおネイサンに置換
gsub("おねえさん", "おネエサン", Test)
[2] "Rのガイド:研究者も、社会人も、おネエサンも。とりあえず、みんなで使ってみませんか?"

#含まれる"の"を全て"が"に置換
gsub("の", "が", Test)
[1] "Rで解析:フォルダがコピーや作成など「pathological」パッケージが紹介とパッケージに依存しない方法"
[2] "Rがガイド:研究者も、社会人も、おねえさんも。とりあえず、みんなで使ってみませんか?"            
[3] "Rで解析:画像がカラーコードを取得する方法!「EBImage」パッケージが紹介"                         
[4] "Rでお遊び:プレゼン資料が配色に使えるかも?キャラクターが髪が色?"

#最初に現れる"の"を"が"に置換
sub("の", "が", Test)
[1] "Rで解析:フォルダがコピーや作成など「pathological」パッケージの紹介とパッケージに依存しない方法"
[2] "Rがガイド:研究者も、社会人も、おねえさんも。とりあえず、みんなで使ってみませんか?"
[3] "Rで解析:画像がカラーコードを取得する方法!「EBImage」パッケージの紹介"
[4] "Rでお遊び:プレゼン資料が配色に使えるかも?キャラクターの髪の色?"

正規表現で文字列を抽出

正規表現でを使用した文字列の抽出例です。

Test <- c("KKKRRADAAA GOODDDDDD",
          "kkkrraaadaaaaGoood",
          "かかからららだだだいもののの",
          "からだにいいもの")

#+の直前文字が1回以上繰り返すを抽出
Test[grep("ら+", Test)]
[1] "かかからららだだだいもののの" "からだにいいもの"  

#文字と[^]の文字列を含まない文字列を抽出
Test[grep("だ[^に]い", Test)]
[1] "かかからららだだだいもののの"

#ある文字を含む文字列を抽出
Test[grep("A|に", Test)]
[1] "KKKRRADAAA GOODDDDDD" "からだにいいもの"  

#特定パターンを抽出
Test[grep("ら.に", Test)]
[1] "からだにいいもの"

#+を組み合わせて特定パターンを抽出
Test[grep("A.+D", Test)]
[1] "KKKRRADAAA GOODDDDDD"

###ここから、使用する文字データ########
Test <- c("karada いいもの", "karadaいい もの",
          "karada_いいもの", "からだにいいもの",
          "からだに1いいもの", "からだに1223いもの",
          "からだに12234535いいもの", "からだに13234535いいもの",
          "からだに13234335いいもの", "0123-45-6789",
          "012-3456-7895", "0123456789")
########

#空白を含む文字列にマッチ
Test[grep("\\s", Test)]
[1] "karada いいもの" "karadaいい もの"

#数字3の前に数字が3連続にマッチ
Test[grep("\\d{3}?3", Test)]
[1] "からだに1223いもの" "からだに12234535いいもの" "からだに13234535いいもの" "からだに13234335いいもの"
[5] "0123-45-6789" "0123456789" 

#数字3が3回以上出現にマッチ
#Test[grep("(3.*){3}", Test)]
Test[grep("(3.*){3,}", Test)]
[1] "からだに13234535いいもの" "からだに13234335いいもの"

#数字3が2連続出現にマッチ
Test[grep("3{2}", Test)]
[1] "からだに13234335いいもの"

#ハイフンありの数字にマッチ
Test[grep("0\\d{1,4}-\\d{1,4}-\\d{4}", Test)]
[1] "0123-45-6789"  "012-3456-7895"

#「いい」を含む文字列がマッチ
Test[grep("\\wいい", Test)]
[1] "karadaいい もの" "karada_いいもの" "からだにいいもの" "からだに1いいもの"       
[5] "からだに12234535いいもの" "からだに13234535いいもの" "からだに13234335いいもの"

#「いい」を含まない文字列がマッチ
Test[grep("(*いい)", Test, invert = TRUE)]
[1] "からだに1223いもの" "0123-45-6789" "012-3456-7895" "0123456789"

#特殊文字(.など)をエスケープ:\\
grep("い\\.い", c("ii", "い.いい", "い. a", "いいい", "い9i", "い.9i"))
[1] 2

#任意の一文字にマッチ:.
grep("い.い", c("ii", "い.いい", "い. a", "いいい", "い9i", "い9i"))
[1] 2 4

#ある文字から開始する文字にマッチ:^,.,*,$の組み合わせ
grep("^いい.*$", c("ii", "い.いい", "い. a", "いいい", "い9i", "い9i"))
[1] 4

#ある文字で終了する文字にマッチ:^,.,*,$の組み合わせ
grep("^.*いい$", c("ii", "い.いい", "い. a", "いいい", "い9i", "い9i"))
[1] 2 4

#英数字にマッチ:[A-Za-z0-9]
grep("[A-Za-z0-9]", c("ii", "い.いい", "い. a", "いいい", "い9i", "い9i"))
[1] 1 3 5 6

#数字にマッチ:[0-9]
grep("[0-9]", c("ii", "い.いい", "い. a", "いいい", "い9i", "い9i"))
[1] 6

#空白にマッチ:[[:space:]]
grep("[[:space:]]", c("ii", "い.いい", "い. a", "いいい", "い9i", "い9i"))
[1] 3

#ある拡張子を含む文字列にマッチ
#例ではwordの.doxcにマッチ
grep("^.*doxc*$", c("ii", "い.いい", "い.doxc", "いいい", "い9i", "い9i"))
[1] 3

#少数点を含む文字列にマッチ
grep("[+-]?\\d*\\.\\d", c("45454", "-8.0", "8.15452", "7.5", ".23", "い9i"))
[1] 2 3 4 5

#https/ftpを含む文字列にマッチ
grep("(https?|ftp)://([^:/]+)",
     c("45454", "-8.0",
       "https://www.karada-good.net/analyticsr/r-648/",
       "7.5", ".23", "https://www.karada-good.net/"))
[1] 3 6

文字列のマッチ確認に便利な「stringr::str_view」コマンド

文字列のマッチの確認は「stringr」パッケージの「str_view」コマンドが便利です。なお、「stringr」パッケージは「ggplot2」パッケージなども収録している「tidyverse」パッケージをインストールして利用するのが便利です。

#tidyverseパッケージの読み込み
#tidyverseパッケージがなければインストール
if(!require("tidyverse", quietly = TRUE)){
  install.packages("tidyverse");require("tidyverse")
}

#文字列例
text <- c("DHA30.0mgEPA100mgARA120mg", "1100mg 400mg",
          "DHA217mgEPA83mg計300mg", "1日当たりDHA300mg",
          "DHA880mg合計964mgEPA84mg",
          "ルテイン10mgアスタキサンチン4mgシアニジン-3-グルコシド2.3mgDHA50mg")

#正規表現パターン
pattern <- "EPA[0-9.]+mg|DHA[0-9.]+mg|^[0-9.]+mg|\\s[0-9.]+mg"

#マッチの確認:str_viewコマンド
str_view(text, pattern)
[1] │ <DHA30.0mg><EPA100mg>ARA120mg
[2] │ <1100mg>< 400mg>
[3] │ <DHA217mg><EPA83mg>計300mg
[4] │ 1日当たり<DHA300mg>
[5] │ <DHA880mg>合計964mg<EPA84mg>
[6] │ ルテイン10mgアスタキサンチン4mgシアニジン-3-グルコシド2.3mg<DHA50mg>

###参考#####
#text <- c("applebananaorange")
#否定の正規表現パターン
#pattern <- "(?<=^apple).*"
#マッチの確認:str_viewコマンド
#str_view(text, pattern)
#[1] │ apple<bananaorange>

文字列のUnicode正規化

「stringi」パッケージの「stri_trans_general」コマンドを利用すると楽に変換できます。文字の表記ゆれの修正に便利だと思います。

#パッケージのインストール
install.packages("stringi")

#パッケージの読み込み
library("stringi")

#文字列例
text <- c("mg", "mg", " ", " ", "α", "β", "γ",
          "。", ".", "/", "/", "3", "3", "A", "a")

#Unicode正規化:NFD,NFC,NFKD,NFKCなどが使用可能
stri_trans_general(text, "NFKC")
#mg" "mg" " "  " "  "α" "β" "γ" "。"
#"."  "/"  "/"  "3"  "3"  "A"  "a" 

#ギリシャ文字をラテン文字に変換
stri_trans_general(text, "greek-latin")
#"mg" "mg"   " "   " "    "a"    "b"    "g" 
#"。"   "."    "/"   "/"    "3"  
#"3"    "A"    "a" 

#大文字を小文字に変換
#逆の場合は"upper"を入力する
stri_trans_general(text, "lower")
#"mg" "mg"   " "   " "    "α"   "β"   "γ" 
#"。"   "."    "/"   "/"    "3"  
#"3"    "a"    "a"   

役に立つ記事の紹介


少しでも、あなたの解析が楽になりますように!!

タイトルとURLをコピーしました