メモ:rlangのquo_name()、quo_text()、quo_label()、as_string()あたりの使い分け

TL;DR

  • quo_name(): 名前のついていない引数に名前をつけるときに使う(例: data.frame(a)とやるとaが列名になる、みたいなこと)
  • quo_label(): quosureや表現式を短めの文字列に変換するときに使う
  • quo_text(): quosureや表現式を省略なしの文字列に変換するときに使う
  • as_string(): シンボルを文字列に変換するときに使う

比較

library(rlang)

f <- list(
  as_string = as_string,
  quo_name = quo_name,
  quo_label = quo_label,
  quo_text = quo_text
)

q <- list(
  invalid_quo = quo(`a + 1`),
  short_quo = quo(a + 1),
  long_quo = quo(a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a),
  normal_call = expr(a + 1),
  normal_sym = sym("a"),
  invalid_sym = sym("a + 1")
)

# purrr::invoke()はsoft-deprecatedになってpurrr::exec()を使うのが推奨らしい
safe_exec <- function(f, q) {
  tryCatch(
    exec(f, q),
    error = function(e) "Error!!!"
  )
}

res <- purrr::map_dfc(
  f,
  ~ paste("<pre>", purrr::map_chr(q, safe_exec, f = .), "</pre>")
)

rownames(res) <- names(q)
#> Warning: Setting row names on a tibble is deprecated.

knitr::kable(res, format = "html", escape = FALSE)
as\_string quo\_name quo\_label quo\_text
invalid\_quo
 Error!!! 
 a + 1 
 `a + 1` 
 `a + 1` 
short\_quo
 Error!!! 
 a + 1 
 `a + 1` 
 a + 1 
long\_quo
 Error!!! 
 +... 
 `+...` 
 a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + 
    a + a + a + a + a 
normal\_call
 Error!!! 
 a + 1 
 `a + 1` 
 a + 1 
normal\_sym
 a 
 a 
 `a` 
 a 
invalid\_sym
 a + 1 
 a + 1 
 `a + 1` 
 `a + 1` 

Created on 2018-11-05 by the reprex package (v0.2.1)

メモ

  • この表を見ると、as_string()エラーばっかりなのは、quo_*()がquosureにも表現式にもなんでも使える一方、as_string()はシンボルにしか使えないからです。 なんて使えないやつ...と思ってしまうかもしれませんが、逆に言うと、「シンボルを文字列に変換したい」ときはas_string()を使っておくとシンボルしか通らないことが保証されるという優れものです。
  • quo_label()は正直使いどころがピンと来ない...。
  • expr_name()expr_label()expr_text()も同種の関数ですが(表現式のみ引数に取れる)、quo_*()の方が上位互換なので今は非推奨になってるみたいです。
  • 英語ブログの方に書いたみたいに、enquo()とかenexpr()はすでに評価されてしまっているプロミスには使えないという問題があります。これに対応するために新しい関数ができるのかも? (Do we need enlabel() and entext()? · Issue #303 · r-lib/rlang · GitHub