# 通知設計書 15-colwise関数のグループ変数無視

## 概要

本ドキュメントは、dplyrパッケージのcolwise関数群（`mutate_all()`, `mutate_if()`, `transmute_all()`, `transmute_if()`など）において、グループ化されたデータフレームに対して操作を行う際に、グループ変数が暗黙的に無視されることを通知する情報メッセージの設計を記載する。

### 本通知の処理概要

colwise関数群（`_all`, `_if`, `_at`接尾辞を持つ関数）は、データフレームの複数列に対して同じ操作を適用する機能を提供する。グループ化されたデータフレームに対して使用する場合、`_all`および`_if`バリアントではグループ変数は暗黙的に操作対象から除外される。

**業務上の目的・背景**：グループ変数に対する操作は通常意図されないが、`_all`や`_if`バリアントではすべての列が対象となるため、ユーザーはグループ変数も操作されると誤解する可能性がある。この通知により、どのグループ変数が無視されるかを明示的に伝え、予期しない動作を防ぐ。なお、これらの関数はsupersededであり、`across()`の使用が推奨される。

**通知の送信タイミング**：`mutate_all()`, `mutate_if()`, `transmute_all()`, `transmute_if()`がgrouped_dfに対して実行される際、`check_grouped()`関数内で通知が発生する。

**通知の受信者**：R言語のコンソールを使用している開発者・データアナリスト。通知はコンソールに直接出力される。

**通知内容の概要**：「`{verb}_{suffix}()` ignored the following grouping variables:」という形式で始まり、無視されるグループ変数名が列挙される。`_all`バリアントでは代替方法も案内される。

**期待されるアクション**：ユーザーは通知を確認し、グループ変数が意図的に除外されていることを理解する。`_at`バリアントで`-group_cols()`を使用するか、`across()`への移行を検討する。

## 通知種別

コンソール情報メッセージ（`inform()`による`message`条件）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（関数実行中に即座に表示） |
| 優先度 | 低（情報通知） |
| リトライ | 無し |

### 送信先決定ロジック

R言語の標準メッセージハンドラを通じてコンソールに出力される。`suppressMessages()`で抑制可能。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| 形式 | テキスト |

### 本文テンプレート（_allバリアントの場合）

```
`{verb}_{suffix}()` ignored the following grouping variables:
* {グループ変数1}
* {グループ変数2}
i Use `{verb}_at(df, vars(-group_cols()), myoperation)` to silence the message.
```

### 本文テンプレート（_ifバリアントの場合）

```
`{verb}_{suffix}()` ignored the following grouping variables:
* {グループ変数1}
* {グループ変数2}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| verb | 操作の種類（mutate/transmute） | 関数名から抽出 | Yes |
| suffix | バリアントの種類（all/if） | 関数名から抽出 | Yes |
| group_vars | グループ変数名のベクトル | `group_vars(tbl)` | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 関数呼び出し | `mutate_all()`/`mutate_if()`/`transmute_all()`/`transmute_if()`の実行 | 入力がgrouped_dfである | `is_grouped_df(tbl)`がTRUE |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 入力がgrouped_dfでない場合 | グループ変数の概念がないため |
| `suppressMessages()`でラップされている場合 | ユーザーが明示的にメッセージを抑制 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[mutate_all等の実行] --> B[check_grouped呼び出し]
    B --> C{入力がgrouped_dfか}
    C -->|No| D[通知なしで処理継続]
    C -->|Yes| E[グループ変数を特定]
    E --> F{altフラグがTRUEか}
    F -->|Yes| G[代替方法を含む通知メッセージ構築]
    F -->|No| H[通知メッセージ構築]
    G --> I[inform関数で通知]
    H --> I
    I --> J[処理継続]
    D --> J
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| 該当なし | - | インメモリデータフレーム操作 |

### テーブル別参照項目詳細

該当なし（データベースは使用しない）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 該当なし | - | この通知自体はエラーではなく情報提供 |

### リトライ仕様

該当なし

## 配信設定

### レート制限

該当なし（即座に1回表示）

### 配信時間帯

該当なし（関数実行時に即座に表示）

## セキュリティ考慮事項

グループ変数名情報がコンソールに出力されるため、機密性の高い変数名が含まれる場合は注意が必要。

## 備考

- これらの関数はsupersededであり、`across()`の使用が推奨される
- `summarise_all()`および`summarise_if()`は暗黙的にグループ変数を無視するが、通知は表示されない（ドキュメントに記載）
- `_at`バリアント（`mutate_at()`, `transmute_at()`など）ではグループ変数の明示的な選択はエラーとなる

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

colwise関数群は`_all`, `_if`, `_at`の3種類のバリアントを持ち、それぞれ異なる方法で列を選択する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | colwise.R | `R/colwise.R` | 1-85行目のドキュメントでscoped verbsの概要を理解 |
| 1-2 | colwise.R | `R/colwise.R` | 55-83行目でグループ変数の扱いについて理解 |

**読解のコツ**: explicit selection（`_at`）とimplicit selection（`_all`, `_if`）の違いが重要。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | colwise-mutate.R | `R/colwise-mutate.R` | 273-285行目の`mutate_all()`関数 |
| 2-2 | colwise-mutate.R | `R/colwise-mutate.R` | 288-301行目の`mutate_if()`関数 |
| 2-3 | colwise-mutate.R | `R/colwise-mutate.R` | 322-334行目の`transmute_all()`関数 |
| 2-4 | colwise-mutate.R | `R/colwise-mutate.R` | 337-350行目の`transmute_if()`関数 |

**主要処理フロー**:
1. **274行目**: `lifecycle::signal_stage("superseded", "mutate_all()")`でsuperseded通知
2. **275行目**: `check_grouped(.tbl, "mutate", "all", alt = TRUE)`で通知（本通知）
3. **276-283行目**: `manip_all()`で操作を構築
4. **284行目**: `mutate(.tbl, !!!funs)`で実行

#### Step 3: 通知ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | colwise-mutate.R | `R/colwise-mutate.R` | 452-472行目の`check_grouped()`ヘルパー関数 |

**主要処理フロー**:
- **453行目**: `is_grouped_df(tbl)`でグループ化されているかチェック
- **454-461行目**: `_all`バリアントの場合、代替方法を含むメッセージを構築
- **462-471行目**: `inform()`で通知を発行

### プログラム呼び出し階層図

```
mutate_all(.tbl, .funs, ...)
    │
    ├─ lifecycle::signal_stage()        # superseded通知
    │
    ├─ check_grouped()                   # 通知(本通知)
    │      │
    │      ├─ is_grouped_df()            # グループ化チェック
    │      │
    │      ├─ group_vars()               # グループ変数名取得
    │      │
    │      └─ inform()                   # 通知発行
    │
    ├─ manip_all()                       # 操作の構築
    │      └─ tbl_nongroup_vars()        # グループ変数を除外
    │
    └─ mutate()                          # 実際の変更
```

### データフロー図

```
[入力]                    [処理]                         [出力]

.tbl (grouped_df) ───┐
                     │
.funs (関数) ────────┼──▶ mutate_all() ──▶ 結果(grouped_df)
                     │         │
... (追加引数) ──────┘         │
                               ├─▶ check_grouped()
                               │        │
                               │        ▼
                               │   [コンソール通知]
                               │   "`mutate_all()` ignored..."
                               │
                               └─▶ manip_all()
                                        │
                                        └─▶ tbl_nongroup_vars()
                                               （グループ変数を除外）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| colwise-mutate.R | `R/colwise-mutate.R` | ソース | mutate/transmute系colwise関数の実装 |
| colwise.R | `R/colwise.R` | ソース | scoped verbsの共通処理とドキュメント |
| grouped-df.R | `R/grouped-df.R` | ソース | grouped_dfクラスとis_grouped_df()の定義 |
| group-data.R | `R/group-data.R` | ソース | group_vars()関数の定義 |
