120  実践 str_trim

library(tidyverse)

ここでは、少しこれまでの話と逆行しますが、正規表現に頼らない方が簡単に処理ができるケースを例示してみます。

正規表現の練習問題2を改めてみてみましょう。次の文字列ベクトルから検査値を抜き出すことが課題でした。

vec <- c("1HbA1c :4.9", "2HbA1c: 6.3", "3HbA1c : 3", "4HbA1c:5")
vec
[1] "1HbA1c :4.9" "2HbA1c: 6.3" "3HbA1c : 3"  "4HbA1c:5"   

ここで、

prac <- tibble(target = vec)
prac
# A tibble: 4 × 1
  target     
  <chr>      
1 1HbA1c :4.9
2 2HbA1c: 6.3
3 3HbA1c : 3 
4 4HbA1c:5   

このTibbleを1つ前の動画のように検査名と値に分けてみましょう。正規表現をごりごり利用する場合は、解答にあったように

prac %>% 
  mutate(
    value = str_extract(target,"(?<=:(\\s|))(\\d+\\.\\d+|\\d+)"),
  
  )
# A tibble: 4 × 2
  target      value
  <chr>       <chr>
1 1HbA1c :4.9 4.9  
2 2HbA1c: 6.3 6.3  
3 3HbA1c : 3  3    
4 4HbA1c:5    5    

検査値の抽出だけでも、ぱっとみ分かりにくい正規表現になっています。ただ、ここで、次のようにすると、見通しがかなりよくなりませんか?

prac %>% 
  mutate(
    left = str_extract(target,"^.+(?=:)"), #コロンの前
    right = str_extract(target,"(?<=:).+$"), #コロンの後
    name = str_trim(left), #コロンの前の空白除去
    value = str_trim(right) #コロンの後の空白除去
  )
# A tibble: 4 × 5
  target      left      right  name   value
  <chr>       <chr>     <chr>  <chr>  <chr>
1 1HbA1c :4.9 "1HbA1c " "4.9"  1HbA1c 4.9  
2 2HbA1c: 6.3 "2HbA1c"  " 6.3" 2HbA1c 6.3  
3 3HbA1c : 3  "3HbA1c " " 3"   3HbA1c 3    
4 4HbA1c:5    "4HbA1c"  "5"    4HbA1c 5    

こんな感じでstr_trim関数を利用してあげると、前後のスペースが消えてくれるので、“(?<=:(\s|))(\d+\.\d+|\d+)”この正規表現を書かなくても、処理することができました

データクリーニングするさいには、そのデータを目的の形へ正確に効率よく変換できればOKなので、色々なやり方を試みてください。

後、str_trimの設定について補足しておきます。

str_trimは

?str_trim
starting httpd help server ... done

のUsageでsideというargumentがあります。

これは、

tgt <- "    S     P      A      C      E      !   "

both <- str_trim(tgt, side = "both")
left <- str_trim(tgt, side = "left")
right <- str_trim(tgt, side = "right")

str_view_all(c(tgt, both, left, right), "\\s")
Warning: `str_view()` was deprecated in stringr 1.5.0.
ℹ Please use `str_view_all()` instead.
[1] │ < >< >< >< >S< >< >< >< >< >P< >< >< >< >< >< >A< >< >< >< >< >< >C< >< >< >< >< >< >E< >< >< >< >< >< >!< >< >< >
[2] │ S< >< >< >< >< >P< >< >< >< >< >< >A< >< >< >< >< >< >C< >< >< >< >< >< >E< >< >< >< >< >< >!
[3] │ S< >< >< >< >< >P< >< >< >< >< >< >A< >< >< >< >< >< >C< >< >< >< >< >< >E< >< >< >< >< >< >!< >< >< >
[4] │ < >< >< >< >S< >< >< >< >< >P< >< >< >< >< >< >A< >< >< >< >< >< >C< >< >< >< >< >< >E< >< >< >< >< >< >!

このように、str_view_allで全部当たる結果をみることができるので見てみると、

bothとした場合は両端のスペースleftで左、rightで右のスペースが削除されていることが確認できます。また、スライドでは紹介していませんが、

?str_trim
tgt
[1] "    S     P      A      C      E      !   "
str_squish(tgt)
[1] "S P A C E !"

中間の無駄なスペースを除去することができます

以上、str_trimの解説でした。

次の動画で、ここまでのstr_xxx系の関数を利用した練習問題を解いてみましょう!