124  応用 全角から半角数字への変換

library(tidyverse)
vec <- c("134.5ml投与","A薬5錠 分3")

日本語のデータ分析を行う場合に、避けては通れないのが、全角の数字が出現している場合の問題です。

正規表現は、数字はあたるはあたります

str_extract(vec,"\\d+")
[1] "134" "5"    

また、日本語も問題なく扱えます。

str_extract(vec,"薬")
[1] NA   "薬"
vec
[1] "134.5ml投与" "A薬5錠 分3"     

が、

str_extract(vec,"(\\d+\\.\\d+)(?=ml)") #X
[1] NA NA

これは、「.」が、全角であるために拾えません。

str_extract(vec,"(\\d+.\\d+)(?=ml)")
[1] "134.5" NA          

また、

as.numeric("5")
Warning: NAs introduced by coercion
[1] NA

と文字列を数字に変更しようとしても、NAが帰ってくるため、全角の数字が出現している場合は半角に早期に戻しておくほうが無難です。

パッケージを利用した方法等もいろいろありますがここでは自作関数を作成する方法を試してみましょう。

str_replace_allはnamed vectorという、名前付きベクトルを与えてあげると複数のパターンに対して置き換えを実施してくれます。

例えば、

test1 <- c("aaa" = "bbb", "AAA" = "BBB")
str_replace_all("aaa<<<>>>AAA", test1)
[1] "bbb<<<>>>BBB"

ということで、

replacer <- c(
  "1" = "1",
  "2" = "2",
  "3" = "3",
  "4" = "4",
  "5" = "5",
  "6" = "6",
  "7" = "7",
  "8" = "8",
  "9" = "9",
  "0" = "0"
)

vec <- c("123","234","567","890")

str_replace_all(vec,replacer)
[1] "123" "234" "567" "890"

とこんな感じで全角を置き換えることができます。この置き換え、関数化しておくと、

num_zen_to_han <- function(vec){
  replacer <- c(
    "1" = "1","2" = "2","3" = "3","4" = "4",
    "5" = "5","6" = "6","7" = "7","8" = "8",
    "9" = "9","0" = "0", "." = "."
  ) 
  
  return(str_replace_all(vec,replacer))
} 

dat <- tibble(tgt = c("123","346.7","34.563"))

dat %>% 
  mutate(han = num_zen_to_han(tgt))
# A tibble: 3 × 2
  tgt         han   
  <chr>       <chr> 
1 123      123   
2 346.7   346.7 
3 34.563 34.563

できました!必要に応じて、実施してみてください