引数 formula をとる関数の変数名を自作関数の引数として渡す方法

結論: rstats::reformulate() を使うとうまくいきました

きょうも R 言語によるデータ解析をサポートしました。 本日のご相談内容は「複数の変数について統計検定をするにあたり、ほぼ同じコードを何度も実行しているのでもっとうまく書きたい」というものでした。

下記のようなケースです:

rstatix::wilcox_test(data = iris, formula = Sepal.Length ~ Species, paired = FALSE)
rstatix::wilcox_test(data = iris, formula = Sepal.Width ~ Species, paired = FALSE)
rstatix::wilcox_test(data = iris, formula = Petal.Length ~ Species, paired = FALSE)
rstatix::wilcox_test(data = iris, formula = Petal.Width ~ Species, paired = FALSE)

確かに共通化したいですね 👀

1st try 🔗

まず、何も考えずふつうに関数化してみました。

my_wilcox <- function(df, response) {
  rstatix::wilcox_test(data = df, formula = response ~ Species, paired = FALSE)
}

一見よさそうに思うのですが、これでは下記のようなエラーが出てしまいます 💣:

> my_wilcox(iris, "Sepal.Width")
Error in `pull()`:
! Can't extract columns that don't exist.
✖ Column `response` doesn't exist.
Run `rlang::last_error()` to see where the error occurred.

問題となっているのは、引数 response です。 意図としては、この response は受け取ったカラム名を展開してから、つまり Sepal.length として評価されてほしいのですが、実際には response というカラムとしてそのまま解釈されてしまっています。

formula を作り直して再チャレンジ 🔗

下記のように、 rstats::refourmulate() を使うことで、変数展開後のカラム名を使って formula 型のオブジェクトを引数 formula に渡せるようになりました。

my_wilcox <- function(df, response) {
  rstatix::wilcox_test(
    data = df,
    formula = reformulate("Species", response = response),
    paired = FALSE
  )
}
> my_wilcox(iris, "Sepal.Length")
# A tibble: 3 × 9
  .y.          group1     group2        n1    n2 statistic        p    p.adj p.adj.signif
  <chr>        <chr>      <chr>      <int> <int>     <dbl>    <dbl>    <dbl> <chr>
1 Sepal.Length setosa     versicolor    50    50     168.  8.35e-14 1.67e-13 ****
2 Sepal.Length setosa     virginica     50    50      38.5 6.4 e-17 1.92e-16 ****
3 Sepal.Length versicolor virginica     50    50     526   5.87e- 7 5.87e- 7 ****

いい感じです 🎉

今日も勉強させてもらいました。ありがとうございます 😌

comments powered by Disqus