# 機能設計書 83-tribble

## 概要

本ドキュメントは、dplyrパッケージが再エクスポートするtribble関数の機能設計を記述する。tribbleは「行指向（transposed tibble）」の形式でtibbleを作成する関数であり、小規模なデータセットやルックアップテーブルを人間が読みやすい形式で定義する際に特に有用である。

### 本機能の処理概要

tribble関数は、チルダ（~）記法を用いて行ごとにデータを定義し、tibbleオブジェクトを作成する機能を提供する。従来のtibble()関数が列指向でデータを定義するのに対し、tribbleは行指向でデータを定義できるため、コード上でデータの内容が視覚的に理解しやすい。

**業務上の目的・背景**：データ分析やテスト作成において、小規模なサンプルデータやルックアップテーブルを定義する機会は多い。tibble()関数では各列をベクトルとして定義するため、行間の対応関係が把握しにくい。tribbleは実際のデータテーブルの見た目に近い形式でコードを記述できるため、コードの可読性が大幅に向上し、データ定義時のミスも防ぎやすくなる。特にマッピングテーブルやパラメータ定義において、各行の意味が明確になる。

**機能の利用シーン**：ルックアップテーブルやマッピングテーブルの定義時、テストデータの作成時、ドキュメント内でのサンプルデータ定義時、シミュレーションパラメータの定義時、小規模なインラインデータセットの作成時などに利用される。大規模データには適さないが、可読性が重要な場面で威力を発揮する。

**主要な処理内容**：
1. チルダ（~）で始まる列名の定義を解析する
2. カンマ区切りの値を行単位で収集する
3. 各値を対応する列に割り当てる
4. tbl_dfクラスを持つtibbleオブジェクトを構築して返す

**関連システム・外部連携**：tribbleはtibbleパッケージで定義され、dplyrパッケージを通じて再エクスポートされる。dplyrのドキュメントや例示コード内で頻繁に使用されており、特にrecode、case_match、rowwiseなどの関数の使用例で多用される。

**権限による制御**：本機能に権限による制御は適用されない。すべてのユーザーが同一の機能を利用可能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | 本プロジェクトはRライブラリであり、画面は存在しない |

## 機能種別

データ構造作成 / オブジェクト生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ... | formula/値 | Yes | 列名（~col_name形式）と値をカンマ区切りで指定。最初にすべての列名を定義し、その後行ごとの値を順に記述する | 列名の数と値の数が対応している必要がある |

### 入力データソース

コード内で直接定義されるフォーミュラおよび値

### 構文形式

```r
tribble(
  ~列名1, ~列名2, ~列名3,
  値1_1,  値1_2,  値1_3,
  値2_1,  値2_2,  値2_3,
  ...
)
```

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (返り値) | tbl_df (tibble) | 入力から構築されたtibbleオブジェクト。クラスは c("tbl_df", "tbl", "data.frame") |

### 出力先

関数の戻り値として呼び出し元に返される

## 処理フロー

### 処理シーケンス

```
1. 引数の解析
   └─ ...引数からフォーミュラと値を分離
2. 列名の抽出
   └─ チルダ（~）で始まる要素を列名として識別
3. 値の収集と検証
   └─ 列数で割り切れる数の値が必要
4. 行への値の割り当て
   └─ 列数ごとに値を区切って各行を構成
5. tibbleオブジェクトの構築
   └─ tibble()を内部的に呼び出してオブジェクト生成
6. 結果の返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: tribble関数呼び出し] --> B[引数を解析]
    B --> C[~で始まる要素を列名として抽出]
    C --> D{列名が1つ以上?}
    D -->|No| E[エラー: 列名が必要]
    D -->|Yes| F[残りの値を収集]
    F --> G{値の数 mod 列数 == 0?}
    G -->|No| H[エラー: 値の数が不正]
    G -->|Yes| I[行数を計算]
    I --> J[列ごとにベクトルを構築]
    J --> K[tibble()で構築]
    K --> L[終了: tibbleを返却]
    E --> M[終了: エラー]
    H --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-83-01 | 列名フォーミュラ | 列名はチルダ（~）で始まる必要がある | 常時適用 |
| BR-83-02 | 値の数の整合性 | 値の総数は列数で割り切れる必要がある | 常時適用 |
| BR-83-03 | 型の推論 | 各列の型は含まれる値から自動的に推論される | 常時適用 |
| BR-83-04 | 行指向レイアウト | 値はコード上で行ごとにグループ化して記述できる（視覚的な整理用） | 推奨パターン |

### 計算ロジック

行数の計算：
```
行数 = 値の総数 / 列数
```

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベース操作を行わない。メモリ内でのデータ構造作成のみを実行する。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | error_tribble_needs_columns | 列名が1つも指定されていない | ~col_name形式で列名を指定する |
| - | error_tribble_incorrect_row_length | 値の数が列数で割り切れない | 値の数を確認し、不足または過剰な値を修正する |
| - | error_incompatible_type | 同一列内で互換性のない型が混在 | 型を統一するか、明示的に変換する |

### リトライ仕様

本機能はステートレスな処理であり、リトライ機構は不要である。

## トランザクション仕様

本機能はデータベーストランザクションを使用しない。

## パフォーマンス要件

- tribbleは小規模データセット向けに設計されており、数十行程度のデータ作成に最適
- 大規模データ（数千行以上）の作成にはtibble()やread_csv()等を使用することを推奨
- 構文解析のオーバーヘッドがあるため、パフォーマンスクリティカルな処理では避ける

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

- コード内に直接値を記述するため、機密データをtribbleで定義しないよう注意
- ソースコード管理システムに機密情報が含まれないよう確認が必要

## 備考

- tribbleはtibbleパッケージで定義され、dplyrを通じて再エクスポートされている
- 名前の由来は「transposed tibble」（転置されたtibble）
- dplyrのドキュメントやexampleで多用されており、特にルックアップテーブル作成のイディオムとして定着

---

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

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

### 推奨読解順序

#### Step 1: 再エクスポートの仕組みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | reexport-tibble.R | `R/reexport-tibble.R` | dplyrがtibbleパッケージからtribbleをエクスポートする仕組み |
| 1-2 | NAMESPACE | `NAMESPACE` | tribbleのエクスポート宣言 |

**読解のコツ**: tribbleはtibbleパッケージの関数をそのまま再エクスポートしている。dplyr側での追加実装はない。

**主要処理フロー**:
1. **17-19行目** (`R/reexport-tibble.R`): `@importFrom tibble tribble` でtibbleパッケージからインポート
2. **18行目**: `@export` でdplyrのエクスポート対象として登録
3. **19行目**: `tibble::tribble` でtibbleパッケージの関数をそのまま再エクスポート

#### Step 2: dplyr内でのtribble使用パターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | rowwise.R | `R/rowwise.R` | シミュレーションパラメータ定義でのtribble使用例 |
| 2-2 | recode.R | `R/recode.R` | ルックアップテーブル定義でのtribble使用例 |
| 2-3 | case-match.R | `R/case-match.R` | マッピングテーブル定義でのtribble使用例 |

**主要処理フロー**:
- **46-51行目** (`R/rowwise.R`): シミュレーションパラメータの定義
  ```r
  params <- tribble(
   ~sim, ~n, ~mean, ~sd,
      1,  1,     1,   1,
      2,  2,     2,   4,
      3,  3,    -1,   2
  )
  ```
- **121-127行目** (`R/recode.R`): ルックアップテーブルの定義
  ```r
  lookup <- tribble(
    ~from, ~to,
    "a", 1,
    "b", 2,
    "c", 3,
    "d", 4
  )
  ```
- **156-163行目** (`R/recode.R`): 数値からのルックアップテーブル
  ```r
  lookup <- tribble(
    ~from, ~to,
    1, "a",
    2, "b",
    3, "c",
    4, "d",
    NA, "M"
  )
  ```

**読解のコツ**: tribbleはdplyrのドキュメント（roxygen2コメント）内の例示コードで多用されている。実際のアプリケーションコードでも同様のパターンで使用することが推奨される。

#### Step 3: case_matchでのtribble活用を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | case-match.R | `R/case-match.R` | case_matchとtribbleの組み合わせパターン |

**主要処理フロー**:
- **86-94行目** (`R/case-match.R`): case_matchとtribbleの連携
- **114-124行目** (`R/case-match.R`): 複数列のルックアップテーブル
- **150-157行目** (`R/case-match.R`): 更新データのtribble定義

#### Step 4: recode_valuesでのtribble活用を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | recode-values.R | `R/recode-values.R` | recode_valuesとtribbleの組み合わせパターン |

**主要処理フロー**:
- **185行目** (`R/recode-values.R`): likertスケールのtribble定義
- **263-265行目** (`R/recode-values.R`): 複雑なtribble構造（リスト列を含む）
  - コメントで「This `tribble()` is more complex than it may appear」と注記

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

```
dplyr::tribble (再エクスポート)
    │
    └─ tibble::tribble (tibbleパッケージの実装)
           │
           ├─ フォーミュラ解析（~col_name）
           │
           ├─ 値の収集と行への分割
           │
           └─ tibble::tibble() - 最終的なtibble構築
                  │
                  └─ tibble::new_tibble() - オブジェクト生成
```

### データフロー図

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

tribble(               ┌────────────────────┐
  ~col1, ~col2,   ────▶│   列名解析         │
  val1,  val2,         │   (~からの抽出)    │
  val3,  val4          └─────────┬──────────┘
)                                │
                       ┌─────────▼──────────┐
                       │   値の収集         │
                       │   (行単位分割)     │
                       └─────────┬──────────┘
                                 │
                       ┌─────────▼──────────┐
                       │   型推論           │
                       └─────────┬──────────┘
                                 │
                       ┌─────────▼──────────┐          tibble
                       │   tibble()構築     │────────▶ (tbl_df)
                       └────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| reexport-tibble.R | `R/reexport-tibble.R` | ソース | tibbleパッケージ関数の再エクスポート定義 |
| NAMESPACE | `NAMESPACE` | 設定 | パッケージのエクスポート宣言 |
| rowwise.R | `R/rowwise.R` | ソース（例示） | tribbleを使用したシミュレーションパラメータ定義例 |
| recode.R | `R/recode.R` | ソース（例示） | tribbleを使用したルックアップテーブル定義例 |
| case-match.R | `R/case-match.R` | ソース（例示） | tribbleを使用したマッピングテーブル定義例 |
| recode-values.R | `R/recode-values.R` | ソース（例示） | tribbleを使用した値変換テーブル定義例 |
| count-tally.R | `R/count-tally.R` | ソース（例示） | tribbleを使用したサンプルデータ定義例 |
