Posted at

ベクトル化されていない関数のベクトル化

More than 1 year has passed since last update.

タイトルのままです。


経緯

全角英数字と半角英数字が混在した文字列のベクトルがあって、全角から半角へと変換させる必要がありました。これにはNipponパッケージのzen2han関数が有名なのですが...

library(Nippon)

x <- c("123A111", "ほげAa")

zen2han(x)
#> Warning in if (Encoding(s) != "UTF-8") s <- iconv(s, from = "", to =
#> "UTF-8"): 条件が長さが 2 以上なので、最初の 1 つだけが使われます
#> [1] "123A111ほげAa"

という感じで警告とともに値を返してはくれるのですが、この場合collapseしてしまいます。これをどうしたら効率的にできるかわからなかったので、r-wakalangで質問しました。


結果

あっという間にいくつかやり方を教えてもらいました。


purrr::map_chrを利用

purrr::map_chrを利用する方法を教えてもらいました:

library(purrr)

map_chr(x, zen2han)
#> [1] "123A111" "ほげAa"

これが今話題のpurrrですね、求めていたものが出ました。purrrも早く勉強しないと。。。


base::Vectorizeを利用

baseVectorize関数があり、これを利用する方法を教えてもらいました:

Vectorize(zen2han)(x)

#> 123A111 ほげAa
#> "123A111" "ほげAa"

まさにベクトル化...!!


base::Vectorizeについて

気になったのでヘルプドキュメントを確認しました。


概要

「指定した関数の引数の挙動をベクトル化するためのラッパー関数を作るもの」とのことです:

Vectorize(FUN, vectorize.args = arg.names, SIMPLIFY = TRUE,

USE.NAMES = TRUE)


引数


  • FUN


    • 適用する関数を指定

    • match.funで探してくるとのこと



  • vectorize.args


    • FUNで指定した関数の引数のうち、ベクトル化させる引数を文字列ベクトルで指定

    • デフォルトではすべての引数をベクトル化



  • SIMPLIFY


    • 処理した結果をシンプルにするかどうか

    • 要するにsapplyのsimplifyと同じ



  • USE.NAMES


    • ...引数が名前を持っていた場合、その名前を使うかどうか

    • このあたりもsapplyとかを参照




説明

これ、要するにvectorize.argsで指定した引数群をmapplyに渡して処理させているとのことです。そのため、SIMPLIFYやUSE.NAMESといったのがあるんですね。納得です。

なお、このVectorizeで返ってくるのはベクトル化された関数です。なので上記のようになります。また以下のように一旦別のオブジェクトとして格納するといい感じになります:

z2h <- Vectorize(zen2han)

z2h(x)
#> 123A111 ほげAa
#> "123A111" "ほげAa"

r-wakalangで教えていただいた皆様、ありがとうございました。

Enjoy!