# 機能設計書 51-lead

## 概要

本ドキュメントは、dplyrパッケージにおける`lead()`関数の機能設計を定義する。`lead()`はベクトルのリード値（次の値）を取得するウィンドウ関数である。

### 本機能の処理概要

**業務上の目的・背景**：時系列データ分析において、現在の観測値と将来の観測値を比較する必要がある場面は多い。例えば、明日の株価と今日の株価を比較して変化率を計算したり、次月の売上予測値と当月の実績を対比させる際に、各行で「次の値」を参照する機能が必要となる。`lead()`関数は、このようなデータの先読み（ルックアヘッド）処理を簡潔に記述するために設計された。

**機能の利用シーン**：時系列分析における前方参照、将来値との差分計算、シーケンシャルデータにおける次要素との比較、ウィンドウ関数を使用したデータ変換処理などで利用される。特に`mutate()`や`summarise()`内でグループ単位の計算を行う際に有用である。

**主要な処理内容**：
1. 入力ベクトル`x`を受け取り、指定された`n`個先の要素値を取得する
2. ベクトルの末尾`n`個の要素については、デフォルト値（指定がなければNA）で埋める
3. `order_by`引数が指定された場合は、その順序に従ってリード計算を行う
4. データフレームや行列などの多次元データにも対応する

**関連システム・外部連携**：vctrsパッケージの`vec_slice()`、`vec_c()`関数を内部で使用する。また、`order_by`引数使用時は`with_order()`関数と連携する。

**権限による制御**：本関数に権限による実行制御は存在しない。

## 関連画面

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

## 機能種別

計算処理 / ウィンドウ関数

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | vector | Yes | リード値を取得する対象ベクトル | ベクトル型であること（ts型は不可） |
| n | integer | No | 先読みする位置数（デフォルト: 1） | 正の整数であること |
| default | any | No | 末尾を埋めるデフォルト値（デフォルト: NULL→NA） | サイズ1でxと型互換であること |
| order_by | vector | No | 順序を定義する補助ベクトル | xと同じサイズであること |
| ... | - | No | 未使用（空であることを確認） | 空であること |

### 入力データソース

Rのベクトル、データフレーム列、または行列。`mutate()`や`summarise()`内で使用される場合は、現在処理中のグループのデータが入力となる。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | vector | 入力と同じ型・サイズのベクトル。各要素は入力ベクトルのn個先の値 |

### 出力先

関数の戻り値として返却される。通常は`mutate()`や`summarise()`の結果としてデータフレームの列に格納される。

## 処理フロー

### 処理シーケンス

```
1. 引数の検証
   └─ nが正の整数であることを確認
   └─ ...が空であることを確認
2. shift()関数の呼び出し
   └─ n を負の値 (-n) として渡す（leadはlagの逆方向）
3. shift()内部処理
   └─ order_byが指定されている場合、with_order()で順序変換
   └─ defaultが指定されている場合、型チェックとキャスト
   └─ shift_slice()またはshift_c()でベクトル操作
4. 結果の返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: lead] --> B{nが正の整数か}
    B -->|No| C[エラー: n must be positive]
    B -->|Yes| D[shift関数を呼び出し n=-n]
    D --> E{order_byが指定されているか}
    E -->|Yes| F[with_order で順序変換して再帰呼び出し]
    E -->|No| G{defaultが指定されているか}
    G -->|Yes| H[shift_c: デフォルト値で埋める]
    G -->|No| I[shift_slice: NAで埋める]
    H --> J[結果ベクトルを返却]
    I --> J
    F --> J
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-51-01 | リード方向 | n個先の値を取得（lagとは逆方向） | 常に適用 |
| BR-51-02 | 末尾パディング | ベクトル末尾n個はdefault値（未指定時NA）で埋める | 常に適用 |
| BR-51-03 | 型保持 | 出力ベクトルは入力と同じ型を維持 | 常に適用 |
| BR-51-04 | 順序制御 | order_by指定時はその順序でリード計算を行う | order_by指定時 |

### 計算ロジック

`lead(x, n)`は以下の処理と等価:
- 出力の1番目からlength(x)-n番目までは、入力のn+1番目からlength(x)番目の値
- 出力のlength(x)-n+1番目からlength(x)番目までは、default値（またはNA）

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

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

本関数はインメモリのベクトル操作のみを行い、データベース操作は行わない。

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 引数エラー | nが正の整数でない | 正の整数を指定する |
| - | 引数エラー | ...に値が渡された（typo等） | 引数名を確認する |
| - | 型エラー | defaultがxと型互換でない | 互換性のある型を指定する |
| - | サイズエラー | order_byがxと異なるサイズ | 同じサイズのベクトルを指定する |

### リトライ仕様

リトライは不要（同期的なインメモリ処理）。

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

トランザクション管理は不要（ステートレスな関数型処理）。

## パフォーマンス要件

- 計算量: O(n)（ベクトルサイズに比例）
- メモリ使用量: O(n)（出力ベクトル用）
- vctrsパッケージの最適化されたベクトル操作を使用

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

特別なセキュリティ考慮事項はない。入力検証は型チェックレベルで行われる。

## 備考

- `lag()`関数と対になる関数で、shiftの方向が逆である
- SQLの`LEAD()`ウィンドウ関数に相当する
- `ts`クラス（時系列オブジェクト）は`stats::lag()`との混乱を避けるためサポートされない

---

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

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

### 推奨読解順序

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

lead/lag関数は、vctrsパッケージのベクトル抽象化に依存している。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | lead-lag.R | `R/lead-lag.R` | lead/lag関数の公開インターフェースと引数定義 |

**読解のコツ**: R言語のroxygen2ドキュメント形式（`#'`で始まるコメント）は関数のドキュメントを生成する。`@param`で引数、`@return`で戻り値を説明している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | lead-lag.R | `R/lead-lag.R` | `lead()`関数の定義（74-83行目） |

**主要処理フロー**:
1. **74-83行目**: `lead()`関数のエントリーポイント
2. **75行目**: `check_dots_empty0(...)`で未使用引数のチェック
3. **77-80行目**: `n`が正の整数であることを検証
4. **82行目**: `shift()`を`n = -n`で呼び出し（負の値でリード方向）

#### Step 3: コア処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | lead-lag.R | `R/lead-lag.R` | `shift()`関数の定義（85-138行目） |

**主要処理フロー**:
- **95-105行目**: `order_by`が指定されている場合、`with_order()`で順序変換後に再帰呼び出し
- **107行目**: `obj_check_vector(x)`でxがベクトルであることを検証
- **112-122行目**: `default`値の検証とキャスト
- **124-131行目**: n値の正規化（絶対値化、サイズ上限チェック）
- **133-137行目**: `shift_slice()`または`shift_c()`の呼び出し

#### Step 4: 低レベル操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | lead-lag.R | `R/lead-lag.R` | `shift_slice()`関数（140-152行目） |
| 4-2 | lead-lag.R | `R/lead-lag.R` | `shift_c()`関数（154-166行目） |

**主要処理フロー**:
- **140-152行目**: `shift_slice()` - NAを使用したパディング処理
  - **141行目**: NA位置のインデックスベクトル作成
  - **147-150行目**: lead方向（lag=FALSE）の場合、後ろにNAを追加
- **154-166行目**: `shift_c()` - ユーザー指定デフォルト値でのパディング
  - **155行目**: デフォルト値をn回複製
  - **161-164行目**: lead方向の場合、後ろにデフォルト値を追加

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

```
lead(x, n, default, order_by, ...)
    │
    ├─ check_dots_empty0(...) [引数検証]
    │
    ├─ check_number_whole(n) [整数検証]
    │
    └─ shift(x, n = -n, default, order_by)
           │
           ├─ [order_by指定時] with_order(order_by, shift, x, ...)
           │      └─ vec_order_radix(order_by)
           │      └─ shift() [再帰呼び出し]
           │
           ├─ obj_check_vector(x) [ベクトル検証]
           │
           ├─ vec_check_size(default, 1) [サイズ検証]
           │
           └─ [default指定時] shift_c(x, n, size, lag=FALSE, default)
              │      └─ vec_rep(default, n)
              │      └─ vec_slice(x, loc)
              │      └─ vec_c(x, default)
              │
              └─ [default未指定] shift_slice(x, n, size, lag=FALSE)
                     └─ vec_rep(NA_integer_, n)
                     └─ vec_slice(x, loc)
```

### データフロー図

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

x = [1,2,3,4,5]  ───▶  lead(x, n=2)                 ───▶  [3,4,5,NA,NA]
                        │
                        └─▶ shift(x, n=-2)
                              │
                              └─▶ shift_slice()
                                    ├─ loc = [3,4,5]
                                    ├─ NA位置 = [NA,NA]
                                    └─ 結合: [3,4,5,NA,NA]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lead-lag.R | `R/lead-lag.R` | ソース | lead/lag関数の実装 |
| order-by.R | `R/order-by.R` | ソース | with_order()関数の実装 |
| test-lead-lag.R | `tests/testthat/test-lead-lag.R` | テスト | lead/lagのユニットテスト |
