glue::glue()をちょっと便利に使う

glueパッケージのglue()は、いわばPythonでいう .format() を使えるようにするパッケージなわけで、以下のようにテンプレートの文字列 (ここでは"a is {a}" )を、その”傍にある”*1 変数で勝手に埋めてくれるので便利に使えるわけです。

> a <- 123
> glue::glue("a is {a}")
a is 123

このテンプレートの文字列に指定する変数は関数の引数になっててもよくて、以下のように使うこともできるのです、おお便利だ!

> f <- function(x)
+ {
+   hoge <- "aaa"
+   glue::glue("{hoge} + {x}")
+ }
> f(123)
aaa + 123

しかし、3連ドット(...)を引数にした場合、その中に所望の変数(ここではx)が入っていたとしても、うまく動きません。

> f <- function(...)
+ {
+   hoge <- "aaa"
+   glue::glue("{hoge} + {x}")
+ }
> f(x=23, y=32)
 Show Traceback
 
 Rerun with Debug
 Error in eval(parse(text = code, keep.source = FALSE), envir) : 
  object 'x' not found 

これを動かすには面倒ですが、

> f <- function(...)
+ {
+   args <- list(...)
+   for(name in names(args)){
+     assign(name, args[[name]])
+   }
+   hoge <- "aaa"
+   glue::glue("{hoge} + {x}")
+ }
> f(x=23, y=32)
aaa + 23

のように、一度3連ドット(...)が絡んでる変数を一度 "f()の環境の変数"としてassignしておく必要があります。
いやいや、これでうごいためでたい。

これを自動でやるようなPull Requestの1つでも出しましょうかねぇ。

*1:実際には (glue::glueの中から見た)parent.frame() = glueの呼び出しもとの環境