# アーキテクチャ設計書

## 概要

本ドキュメントは、Rパッケージ「dplyr」のアーキテクチャ設計について記載する。dplyrは、データフレームの操作を行うための「データ操作の文法（Grammar of Data Manipulation）」を提供するパッケージであり、tidyverseエコシステムの中核をなすコンポーネントである。

本パッケージは、R言語とC++の混成構造を持ち、高パフォーマンスなデータ操作を実現するとともに、直感的なAPIを提供する設計となっている。

## システム全体構成

### アーキテクチャ概要図

システム全体のアーキテクチャ構成図については、[アーキテクチャ構成図.md](./アーキテクチャ構成図.md)を参照のこと。

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| tibble | R関数呼び出し | データフレーム基盤の提供 |
| vctrs | R関数呼び出し | ベクトル操作・型システム |
| rlang | R関数呼び出し | 非標準評価（NSE）・tidy evaluation |
| tidyselect | R関数呼び出し | 列選択ヘルパー |
| pillar | R関数呼び出し | 表示フォーマット |
| magrittr | R関数呼び出し | パイプ演算子（`%>%`）の再エクスポート |
| glue | R関数呼び出し | 文字列補間 |
| lifecycle | R関数呼び出し | 非推奨機能の管理 |
| R6 | R関数呼び出し | DataMaskクラスの実装 |
| dbplyr | R関数呼び出し（オプション） | データベースバックエンド |
| dtplyr | R関数呼び出し（オプション） | data.tableバックエンド |
| arrow | R関数呼び出し（オプション） | Apache Arrowバックエンド |

## レイヤー構成

### アーキテクチャスタイル

dplyrは**ドメイン特化言語（DSL）パターン**と**S3ジェネリックメソッドパターン**を組み合わせた設計を採用している。

主要な設計パターンは以下の通り：

1. **Verb-based API**: 各操作を「動詞」として定義（mutate, filter, select等）
2. **Generic Functions**: S3ジェネリックによる多態性の実現
3. **Data Mask Pattern**: 非標準評価によるデータコンテキスト内での式評価
4. **Lazy Evaluation**: パフォーマンス最適化のための遅延評価

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| Public API | ユーザー向けインターフェース | `mutate()`, `filter()`, `select()`, `summarise()`, `arrange()`, `join*()`, `group_by()` |
| Core Verbs | 各動詞の実装ロジック | `mutate.data.frame`, `filter.data.frame`, `summarise.data.frame` |
| Data Mask | 非標準評価の実行環境 | `DataMask` (R6クラス), `data-mask.R` |
| Grouped Operations | グループ化処理の管理 | `grouped_df`, `rowwise_df`, `compute_groups()` |
| Backend Interface | 外部バックエンドとの連携 | `src.R`, `dbplyr.R`, `compat-dbplyr.R` |
| Native Layer | C++による高速処理 | `src/filter.cpp`, `src/mutate.cpp`, `src/summarise.cpp`, `src/group_by.cpp` |

### レイヤー間の依存関係ルール

```
[Public API]
     ↓
[Core Verbs]
     ↓
[Data Mask] ←→ [Grouped Operations]
     ↓
[Native Layer (C++)]
     ↓
[External Dependencies (vctrs, rlang, tibble)]
```

**依存方向**:
- 上位レイヤーから下位レイヤーへの依存のみ許可
- Native LayerはR API経由でのみ呼び出し
- External DependenciesはCore Verbs以下のすべてのレイヤーから参照可能

**禁止される参照**:
- Native LayerからPublic APIへの直接呼び出し
- 循環依存

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| Single Table Verbs | 単一データフレーム操作 | `mutate.R`, `filter.R`, `select.R`, `summarise.R`, `arrange.R`, `slice.R`, `distinct.R` |
| Two-Table Verbs | 結合操作 | `join.R`, `join-by.R`, `join-cols.R`, `join-rows.R`, `sets.R` |
| Grouping | グループ化操作 | `group-by.R`, `group-data.R`, `group-map.R`, `grouped-df.R`, `rowwise.R` |
| Column Operations | 列操作 | `across.R`, `relocate.R`, `rename.R`, `bind-cols.R`, `bind-rows.R` |
| Row Operations | 行操作 | `rows.R`, `sample.R` |
| Helper Functions | ヘルパー関数 | `case-when.R`, `case-match.R`, `coalesce.R`, `if-else.R`, `recode.R` |
| Context Functions | コンテキスト関数 | `context.R`, `pick.R` |
| Backend Support | バックエンド連携 | `dbplyr.R`, `src.R`, `tbl.R` |

### パッケージ構造

```
dplyr/
├── R/                              # Rソースコード
│   ├── dplyr.R                     # パッケージ定義
│   ├── mutate.R                    # mutate動詞
│   ├── filter.R                    # filter動詞
│   ├── select.R                    # select動詞
│   ├── summarise.R                 # summarise動詞
│   ├── arrange.R                   # arrange動詞
│   ├── join.R                      # join動詞群
│   ├── join-by.R                   # join_by()実装
│   ├── join-cols.R                 # 結合列処理
│   ├── join-rows.R                 # 結合行処理
│   ├── group-by.R                  # group_by動詞
│   ├── grouped-df.R                # grouped_dfクラス
│   ├── rowwise.R                   # rowwise処理
│   ├── data-mask.R                 # DataMaskクラス（R6）
│   ├── context.R                   # cur_*()関数群
│   ├── across.R                    # across()実装
│   ├── slice.R                     # slice動詞
│   ├── distinct.R                  # distinct動詞
│   ├── relocate.R                  # relocate動詞
│   ├── rename.R                    # rename動詞
│   ├── rows.R                      # rows_*()関数群
│   ├── bind-rows.R                 # bind_rows()
│   ├── bind-cols.R                 # bind_cols()
│   ├── sets.R                      # 集合演算
│   ├── case-when.R                 # case_when()
│   ├── case-match.R                # case_match()
│   ├── coalesce.R                  # coalesce()
│   ├── if-else.R                   # if_else()
│   ├── recode.R                    # recode()
│   ├── rank.R                      # ランク関数
│   ├── nth-value.R                 # first(), last(), nth()
│   ├── lead-lag.R                  # lead(), lag()
│   ├── dbplyr.R                    # dbplyr連携
│   ├── src.R                       # データソース
│   ├── tbl.R                       # tblインターフェース
│   ├── generics.R                  # S3ジェネリック定義
│   ├── conditions.R                # エラー/警告処理
│   ├── colwise-*.R                 # 廃止予定のcolwise関数群
│   ├── deprec-*.R                  # 廃止予定関数
│   ├── defunct*.R                  # 廃止済み関数
│   ├── import-standalone-*.R       # スタンドアロン依存
│   ├── reexport-*.R                # 再エクスポート
│   ├── utils*.R                    # ユーティリティ
│   └── zzz.R                       # パッケージロード処理
├── src/                            # C++ソースコード
│   ├── dplyr.h                     # 共通ヘッダー
│   ├── utils.h                     # ユーティリティヘッダー
│   ├── init.cpp                    # R連携初期化
│   ├── imports.cpp                 # 外部パッケージ連携
│   ├── filter.cpp                  # filter処理
│   ├── mutate.cpp                  # mutate処理
│   ├── summarise.cpp               # summarise処理
│   ├── group_by.cpp                # グループ化処理
│   ├── group_data.cpp              # グループデータ管理
│   ├── chop.cpp                    # vec_chop処理
│   ├── mask.cpp                    # データマスク処理
│   ├── reconstruct.cpp             # データ再構成
│   ├── slice.cpp                   # slice処理
│   └── funs.cpp                    # 累積関数
├── man/                            # ドキュメント
├── tests/                          # テスト
│   └── testthat/                   # testthatテスト
├── vignettes/                      # ビネット
├── data/                           # サンプルデータ
├── DESCRIPTION                     # パッケージメタデータ
├── NAMESPACE                       # 名前空間定義
└── NEWS.md                         # 変更履歴
```

### コンポーネント依存関係

**Core Verb Dependencies**:
```
mutate.R → data-mask.R → context.R
         → grouped-df.R
         → across.R

filter.R → data-mask.R → context.R
         → grouped-df.R

summarise.R → data-mask.R → context.R
            → grouped-df.R

join.R → join-by.R
       → join-cols.R
       → join-rows.R

group-by.R → grouped-df.R
           → group-data.R
```

## ミドルウェア構成

### データベース

| 種類 | ミドルウェア | バージョン | 用途 |
| --- | --- | --- | --- |
| RDB | DBI/RSQLite/RMySQL/RPostgres | 各種 | dbplyrを通じたデータベース操作（オプション） |

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| 該当なし | - | - | - |

dplyrはインメモリデータ処理を主とし、キャッシュミドルウェアは使用しない。

### メッセージキュー

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| 該当なし | - | - |

### 検索エンジン

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| 該当なし | - | - |

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| C++ (via Rcpp互換) | R 4.1.0以上 | 高速処理の実装 |
| vctrs | 0.7.1以上 | ベクトル操作・型システム |
| rlang | 1.1.7以上 | 非標準評価エンジン |

## データフロー

### リクエスト処理の流れ

**mutate()の処理フロー**:

1. ユーザーが`mutate(df, new_col = expr)`を呼び出し
2. `mutate()`ジェネリック関数がディスパッチ
3. `mutate.data.frame()`が呼び出される
4. `.by`引数の処理（`compute_by()`）
5. `mutate_cols()`で式を評価
   - `DataMask`インスタンスの作成
   - 各式（quosure）をイテレーション
   - `expand_pick()`, `expand_across()`で式を展開
   - `mutate_col()`で各列を計算
   - C++関数`dplyr_mask_eval_all_mutate`で評価
6. `dplyr_col_modify()`で結果をデータフレームに追加
7. `mutate_relocate()`で列位置を調整
8. `mutate_keep()`で保持する列を選択
9. 結果のデータフレームを返却

### 非同期処理の流れ

dplyrは同期処理のみをサポート。非同期処理は実装されていない。

ただし、遅延評価（Lazy Evaluation）は以下の場面で使用される：

1. `DataMask`内での`chops`（列チャンク）の遅延生成
2. dbplyrバックエンド使用時のクエリ遅延実行
3. 式（quosure）の遅延評価

### データ永続化の流れ

dplyrはインメモリ処理のパッケージであり、直接的なデータ永続化機能は持たない。

データ保存は以下の方法で行う：
- `readr::write_csv()`等の外部関数
- `dbplyr`を通じたデータベース書き込み
- `arrow`を通じたParquet/Arrow形式保存

## 横断的関心事

### 認証・認可

| 方式 | 実装箇所 | 対象 |
| --- | --- | --- |
| 該当なし | - | - |

dplyrはデータ操作ライブラリであり、認証・認可機能は持たない。データベース接続時の認証はDBIパッケージが担当する。

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| 警告メッセージ | `cli`パッケージ経由 | 標準エラー出力 |
| 情報メッセージ | `inform()`/`message()` | 標準エラー出力 |
| 非推奨警告 | `lifecycle::deprecate_warn()` | 標準エラー出力 |

### エラーハンドリング

エラーハンドリングの方針：
- `rlang`パッケージの`abort()`による構造化エラー
- `conditions.R`でエラーコンテキストを管理
- グループ処理中のエラーは詳細なコンテキスト情報を提供

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| 型エラー | `abort()`でエラー投げ | クラス付きcondition |
| サイズ不一致 | `dplyr:::mutate_incompatible_size`等の内部クラス | 詳細エラーメッセージ |
| グループ内エラー | `dplyr_error_handler()`でラップ | グループコンテキスト付きエラー |
| 警告 | `dplyr_warning_handler()`で収集・集約 | 集約された警告メッセージ |
| 非推奨機能 | `lifecycle::deprecate_warn()` | 非推奨警告メッセージ |

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| 該当なし | - | - |

dplyr自体はトランザクション管理を持たない。dbplyrを通じたデータベース操作時は、DBIの`dbBegin()`/`dbCommit()`/`dbRollback()`を使用する。

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| Single Responsibility | 各動詞関数 | `mutate()`は列追加のみ、`filter()`は行フィルタのみ |
| Open/Closed | S3ジェネリック | 新しいデータ型に対してメソッドを追加可能 |
| Interface Segregation | Public API | ユーザー向け関数と内部関数の明確な分離 |
| Dependency Inversion | バックエンド設計 | `UseMethod()`によるディスパッチ |
| Composition over Inheritance | 動詞の組み合わせ | パイプ演算子による関数合成 |
| Fail Fast | バリデーション | 入力検証を各関数の冒頭で実施 |
| Tidy Evaluation | 式評価 | data-maskingによる直感的な列参照 |

### コーディング規約

**命名規約**:
- 公開関数: `snake_case`（例：`group_by`, `left_join`）
- 内部関数: `snake_case`（非エクスポート）
- S3メソッド: `verb.class`（例：`mutate.data.frame`）
- C++関数: `dplyr_` prefix（例：`dplyr_mask_eval_all`）

**ファイル構成**:
- 1ファイル1機能を原則
- 関連するヘルパー関数は同一ファイル内
- 廃止予定関数は`deprec-*`、廃止済みは`defunct*`に分離

**ドキュメント**:
- roxygen2によるドキュメント生成
- `@family`タグによる関連関数のグループ化
- `@section`による詳細説明

**テスト**:
- testthatフレームワーク使用
- 各動詞に対応するテストファイル

## 備考

### バージョン情報

- パッケージバージョン: 1.2.0.9000（開発版）
- R要件: R 4.1.0以上
- ドキュメント生成日: 2026-02-19

### 関連ドキュメント

- [アーキテクチャ構成図](./アーキテクチャ構成図.md)
- [tidyverse.org - dplyr](https://dplyr.tidyverse.org)
- [R for Data Science - Data Transformation](https://r4ds.hadley.nz/data-transform)
