Rのggplotで列名を変数として引数に与えたい

# 用途
ggplotなどtidyverse系列で列名に対して
繰り返し処理や関数を作成したいことがある。

一筋縄でいけないことが多いので、ここに攻略法をまとめた。

そもそも、mapやfacet、acrossでうまくいくことが多いので、それらでは本当にだめか確認する。

# Code
- R / 4.1.0
- Install packages
    - tidyverse

## テストCode

irisについて、各指標で箱ひげ図を得たいとする
一つならこう書ける

```R
iris %>%
    ggplot(aes(x = Species, y = Sepal.Length)) +
    geom_boxplot()
```

<img width="500" alt="image.png (6.7 kB)" src="https://img.esa.io/uploads/production/attachments/15444/2022/10/31/82644/1fcc3d33-aa05-4cef-ab9b-1e8f9c844a24.png">

## ミス Code
あるあるケース

```R
sp_boxplot <- function(var) {
    iris %>%
        ggplot(aes(x = Species, y = var)) +
        geom_boxplot()
}

sp_boxplot("Sepal.Length")
```
<img width="500" alt="image.png (5.5 kB)" src="https://img.esa.io/uploads/production/attachments/15444/2022/10/31/82644/05e99145-043f-4596-8083-861819c1cbab.png">

## クリアCode
いくつか列挙する出力の図はどれも同じ

### aesのパワープレイ
aesは ... を介すると受け取った引数をいい感じに処理するのでうまくいく
```R
sp_boxplot <- function(...) {
    iris %>% 
        ggplot(aes(x=Species,...)) +
        geom_boxplot()
}

sp_boxplot(y=Sepal.Length)
```

### aes_string
引数を文字列で与える
""との組合せのみうまくいく
```R
sp_boxplot <- function(var) {
    iris %>%
        ggplot(aes_string(x = "Species", y = var)) +
        geom_boxplot()
}

sp_boxplot("Sepal.Length")
```

### aes_
引数を列名として宣言する
quote と as.name の適用のみうまくいく
```R
sp_boxplot <- function(var) {
    iris %>%
        ggplot(aes_(x = quote(Species), y = as.name(var))) +
        geom_boxplot()
}

sp_boxplot("Sepal.Length")
```

### !!のアンクォートとquo
クォージャーとして与えて、関数内部で!!によってアンクォート
使うときに、quoで包む必要があるがうまくいく
```R
sp_boxplot <- function(var) {
    iris %>%
        ggplot(aes(x = Species, y = !!var)) +
        geom_boxplot()
}

sp_boxplot(quo(Sepal.Length))
```

### enquo
上のquo処理を関数内部に移管したイメージ
使うときに裸の変数名となるがうまくいく
```R
sp_boxplot <- function(var) {
    var <- enquo(var)
    iris %>%
        ggplot(aes(x = Species, y = !!var)) +
        geom_boxplot()
}

sp_boxplot(Sepal.Length)
```

### {{ }} curly-curly
enquoの後継としてでてきたらしい
使うときに裸の変数名となるがうまくいく
```R
sp_boxplot <- function(var) {
    iris %>%
        ggplot(aes(x = Species, y = {{ var }})) +
        geom_boxplot()
}

sp_boxplot(Sepal.Length)
```

### データ要素として指定
.data（ここではパイプで渡されたiris）の要素ということを明示的にかく
```R
sp_boxplot <- function(var) {
    iris %>%
        ggplot(aes(x = Species, y =.data[[ var ]])) +
        geom_boxplot()
}


sp_boxplot("Sepal.Length")
```

## 結論
公文書に従うなら、
```aes()```か```{{``` でやっていくのが妥当だが、
普段使いには、文字列を渡すことが多いので、文字指定できるものが便利

## あとがき
基本的に問題は2つ
- 引数を変数名か、定数（文字列）のどちらで処理するか
- 変数名として、グローバルなのかデータ内の列名なのか
でうまく回らないことが多い。
そもそも、tidyverseの世界で、列名なら裸（クォーテーション無）で指定できているのが便利でありながらも、問題を生む温床である。
気になる人は、「非標準評価(NSE)」や「tidy eval」で検索検索！

また、今回はaesのなかで分けているが、group_byや別のところでも使うことは可能

今回の手法をまとめると
- aes × enquo のグループ
    - aes × {{ は aes × enquo と等価
    - aes × … は aes × {{ と仕組みは同じだが、関数がどういうふうに使われるべきかによって選択する
- aes_ (aes_q) × quote (ないし ~) のグループ
    - aes_string に比べると X$1 などの扱いが楽
    - ただし soft-deprecated
- aes_string × 文字列のグループ
    - aes_ に比べると X$1 などの扱いがやや面倒
    - ただし soft-deprecated
    -ただし aes_string の代わりに aes(x = .data[[var]]) などとすれば文字列で変数を指定することが可能

## 参考文献
[公文書１：aes_string と aes_](https://ggplot2.tidyverse.org/reference/aes_.html)
[公文書２：enquo や {{](https://ggplot2.tidyverse.org/reference/aes_.html)
[メモ：dplyr・ggplot2 で {{ }} を使う](https://notchained.hatenablog.com/entry/2021/01/20/222608)
[読書日記-2017年8月19日 (土)](https://elsur.jpn.org/mt/2017/08/002494.html)

## スペシャルサンクス
本質問は、Rのslackコミュニティ「[r-wakalang](https://qiita.com/uri/items/5583e91bb5301ed5a4ba)」にて議論させていただきました。