Code
# CSVファイルの読み込み
<- read.csv("ch03_daily_stock_return.csv") daily_stock_return
2024/04/26
2024/04/26
,
) で区切って書いたテキスト・ファイルのことを指す..xlsx
ファイル)を思い浮かべるかもしれないが,特定のアプリケーションに依存したファイル形式だと,互換性がなくて他の環境では開けない恐れがある.したがって,テキストファイルに値とカンマだけで内容を書き込み,互換性を高めたファイル形式がCSVファイルである.read.csv()
関数を使ったCSVファイルの読み込みread.csv()
関数が用意されている.read.csv()
関数には数多くのオプション引数が存在するが,それらをいったん無視して,ファイルのパスをダブルクォーテーション(""
)で囲って引数に指定すれば良い.ch03_daily_stock_return.csv
がコードと同じ作業ディレクトリに位置しているなら,上のように"ch03_daily_stock_return.csv"
という相対パスのみ指定すれば,Rはそのファイルを発見できる.もし上のコードを実行して,次のようなエラーが出る場合,Rはch03_daily_stock_return.csv
を発見できていない.ch03_daily_stock_return.csv
から変更されていないことを確認しよう.繰り返し同じファイルをダウンロードしているとch03_daily_stock_return(1).csv
のように,勝手に名前が変更されてしまう場合がある.daily_stock_return
の詳細の確認head()
関数を用いて,コンソール上でdaily_stock_return
の冒頭6行を出力してみる. date firm1 firm2
1 2020-04-01 -0.039482142 0.076962597
2 2020-04-02 0.005978689 -0.007248848
3 2020-04-03 0.055786605 -0.017304080
4 2020-04-06 0.041934669 0.002168957
5 2020-04-07 -0.020192796 0.075545365
6 2020-04-08 -0.002294705 -0.096211744
nrow()
関数を用いて,何営業日分の株価を含んでいるか確認してみよう.ここで,nrow
はnumber of rows(行数)の略である.daily_stock_return
の詳細の確認daily_stock_return
の各列の名前やデータ型を確認したい.str()
関数を用いてdaily_stock_return
の内部構造を調べてみよう.str
はstructure(構造)の略で,変数の内部構造を意味する.'data.frame': 21 obs. of 3 variables:
$ date : chr "2020-04-01" "2020-04-02" "2020-04-03" "2020-04-06" ...
$ firm1: num -0.03948 0.00598 0.05579 0.04193 -0.02019 ...
$ firm2: num 0.07696 -0.00725 -0.0173 0.00217 0.07555 ...
21 obs. of 3 variables
より,三変数について,21の観測値が収録されていることが確認できる.chr
)のdate
num
)のfirm1
num
)のfirm2
daily_stock_return
の詳細の確認firm1
)と企業2 (firm2
)の株式の日次リターンについて,平均的に見てどちらのリターンが高かったのか,mean()
関数を用いて確認してみよう.$
演算子を用いると列名で各列を参照できることを思い出そう. firm_ID name industry
1 1 Firm A Machinery
2 2 Firm B Chemicals
3 3 Firm C Machinery
firm_data
というデータフレームを作成すると,firm_ID
列は数値型,name
列とindustry
列が文字型となる.industry
列はカテゴリカル変数と呼ばれ,各観測データがどのサブカテゴリーに属するかを明らかにする役割を果たしている.
'data.frame': 3 obs. of 3 variables:
$ firm_ID : num 1 2 3
$ name : chr "Firm A" "Firm B" "Firm C"
$ industry: Factor w/ 2 levels "Chemicals","Machinery": 2 1 2
as.factor()
関数は,データ列をファクター型に変換する関数.str()
関数を用いて構造を眺めてみると,name
列が文字型 (chr
)のままであるのに対し,industry
列はファクター型 (Factor
)に変換済."Chemicals"
と"Machinery"
は水準 (level
)と呼ばれ,各カテゴリーの名前を表す.コンピュータ内部では各カテゴリーが自然数で表されており,今回の観測データはその番号を介して,2 (Machinery)
,1 (Chemicals)
,2 (Machinery)
と表現されている.\[ \begin{align*} \underbrace{\mathit{PV}}_{\textbf{現在価値}}= \frac{\overbrace{CF_1}^{\textbf{1年後の確実なキャッシュフロー}}}{\underbrace{1 + R_{F}}_{\textbf{無リスク金利$R_F$で割り引く}}} \end{align*} \]
\[ \begin{align*} \underbrace{\mathit{PV}}_{\textbf{現在価値}} &= \frac{\overbrace{CF_T}^{\textbf{$T$年後の確実なキャッシュフロー}}}{\underbrace{(1+R_F)^ {T}}_{\textbf{$T$年分だけ無リスク金利$R_F$で割り引く}}} \end{align*} \]
tidyverse
パッケージとは?tidyverse
と呼ばれるパッケージ群である.以下が,それに含まれる主なパッケージ一覧である.名称 | 使用用途 |
---|---|
ggplot2 |
グラフの描画によるデータの可視化 |
dplyr |
データの加工や操作に便利な関数の提供 |
tidyr |
雑然データを整然データの形式に変換する関数の提供 |
readr |
CSVファイルなどの高速,かつ,ユーザー・フレンドリーな読み込み |
tibble |
データフレームを改良したtibble というデータ形式の提供 |
tidyverse
パッケージのインストールinstall.packages()
関数を用いて,第一引数にインストールしたいパッケージ名を""
で囲って指定する.ggplot2
による作図 — 作図データの準備\(R_{F}\)が0.1から0.01刻みで0.2まで変化するときの1年後の確実なキャッシュフロー100の現在価値を求め,割引率に応じて現在価値がどのように変化するか可視化してみよう.
100
というのは1次元のスカラー(一つの実数)であり,R
は11次元のベクトルである.したがって,次式を計算しようとすると,両者の次元が一致しておらず,数学的には不完全な式となっている. \[
PV = \frac{\overbrace{100}^{\textbf{スカラー}}}{1 + \underbrace{\text{R}}_{\textbf{11次元のベクトル}}}
\]ggplot2
による作図 — データフレームの準備ggplot2
は,入力データをデータフレームの形式で準備する必要があるので,まずはdata.frame()
関数を使って 新たなデータフレームfigure_data
を作成しよう.ggplot2
による作図 — tidyverse
パッケージの読み込みggplot2
パッケージを使うためには,library()
関数を使ってtidyverse
を利用することを冒頭で宣言する必要がある.pacman::p_load()
を利用する.ggplot2
のgg
とは
grammar of graphicsの略である.ggplot2
では,グラフの構成要素を各種のレイヤーに分解し,コード上でそれを積み重ねていく形でグラフを作図する.
ggplot2
による作図 — data
引数の指定ggplot()
関数により,作図用キャンバスを準備し,入力データを指定.data = figure_data
として,figure_data
を入力用データとして用いることを宣言している.+
演算子を用いてレイヤーを足していく形で図を作成する.geom_line()
関数である.mapping
引数のaes()
関数では,\(x\)軸と\(y\)軸の要素をラベル名で指定している.ggplot2
による作図 — 散布図の追加ggplot2
の使い方に慣れるために,先ほどの折れ線グラフに各データを表す点を追加してみよう.geom_point()
であるから,+
演算子を用いてそれを先ほどのコードに追加すると,散布図が上書きされる.ggplot2
による作図 — その他の調整Discount Rate
とPresent Value
へと変更しよう.labs()
関数を使えば簡単にできる.theme_classic()
関数は,グラフの背景や枠線など(グラフのテーマと言う)を統一的に変更するための関数である.theme_void()
や,背景は白だがメモリを表す十字線が入るtheme_bw()
など,複数の選択肢があるので,目的に応じて使い分けると良いだろう.ggplot2
を駆使して描画せよ.なお,\(x\)軸のラベルはyear
,\(y\)軸のラベルはPresent Value
とすること.完全に無リスクの資産は存在しないが,実務的には国債金利を無リスク金利のベンチマークとすることが標準的である.↩︎
---
title: "3 tidyverseパッケージを利用した財務データ分析入門"
date: 2024/04/26
format:
html: default
revealjs:
output-file: 3_tidyverse_slide.html
---
## データフレーム(教科書第3.5節)
### データフレーム入門 --- CSVファイルの読み込み
- CSVとは,[**Comma-Separated-Values**]{style="color: red"}(カンマで区切られた値の集合)の略で,値や項目をカンマ (`,`) で区切って書いたテキスト・ファイルのことを指す.
- 表形式のデータと言うとExcelファイル (`.xlsx`ファイル)を思い浮かべるかもしれないが,特定のアプリケーションに依存したファイル形式だと,互換性がなくて他の環境では開けない恐れがある.したがって,テキストファイルに値とカンマだけで内容を書き込み,互換性を高めたファイル形式がCSVファイルである.
------------------------------------------------------------------------
### `read.csv()`関数を使ったCSVファイルの読み込み
- CSVファイルを読み込むために,Rの基本パッケージに`read.csv()`関数が用意されている.`read.csv()`関数には数多くのオプション引数が存在するが,それらをいったん無視して,ファイルのパスをダブルクォーテーション(`""`)で囲って引数に指定すれば良い.
```{r}
# CSVファイルの読み込み
daily_stock_return <- read.csv("ch03_daily_stock_return.csv")
```
- ファイルのパスとは,各ファイルのコンピュータ内部における住所のようなもので,相対パスと絶対パスの二種類が存在する.`ch03_daily_stock_return.csv`がコードと同じ作業ディレクトリに位置しているなら,上のように`"ch03_daily_stock_return.csv"`という相対パスのみ指定すれば,Rはそのファイルを発見できる.もし上のコードを実行して,次のようなエラーが出る場合,Rは`ch03_daily_stock_return.csv`を発見できていない.
------------------------------------------------------------------------
### エラーへの対処
![](images/Fch03_36_SS.png){width="75%"}
- このエラーが表示された場合,まずはダウンロードしたファイルの名前が`ch03_daily_stock_return.csv`から変更されていないことを確認しよう.繰り返し同じファイルをダウンロードしていると`ch03_daily_stock_return(1).csv`のように,勝手に名前が変更されてしまう場合がある.
- ファイル名の一致を確認した上で上記のエラーが表示され続ける場合,このCSVファイルが作業ディレクトリに位置していない可能性が高い.まずはこのCSVファイルが位置する場所(デスクトップなど)を確認した上で,Rの作業ディレクトリをその場所へと変更してみよう.RStudioを使っている場合,上部のタブのうち\[Session\] $\rightarrow$ \[Set Working Directory\] $\rightarrow$ \[Choose Directory\]で作業ディレクトリを指定するのが最も簡単である.
------------------------------------------------------------------------
### `daily_stock_return`の詳細の確認
- 通常,外部のデータセットを読み込んで最初に行うことは,目視でその概要を掴むことである.まずは`head()`関数を用いて,コンソール上で`daily_stock_return`の冒頭6行を出力してみる.
```{r}
# データフレームの冒頭を確認
head(daily_stock_return)
```
- 次は,`nrow()`関数を用いて,何営業日分の株価を含んでいるか確認してみよう.ここで,`nrow`はnumber of rows(行数)の略である.
```{r}
# データフレームの行数を確認
nrow(daily_stock_return)
```
------------------------------------------------------------------------
### (続)`daily_stock_return`の詳細の確認
- 今度は`daily_stock_return`の各列の名前やデータ型を確認したい.`str()`関数を用いて`daily_stock_return`の内部構造を調べてみよう.`str`はstructure(構造)の略で,変数の内部構造を意味する.
```{r}
# データフレームの内部構造を確認
str(daily_stock_return)
```
- `21 obs. of 3 variables`より,三変数について,21の観測値が収録されていることが確認できる.
- 加えて,三変数の具体的な中身は,以下の通りです.
- 文字型 (`chr`)の`date`
- 数値型 (`num`)の`firm1`
- 数値型 (`num`)の`firm2`
------------------------------------------------------------------------
### (続)`daily_stock_return`の詳細の確認
- 次は,企業1 (`firm1`)と企業2 (`firm2`)の株式の日次リターンについて,平均的に見てどちらのリターンが高かったのか,`mean()`関数を用いて確認してみよう.
- `$`演算子を用いると列名で各列を参照できることを思い出そう.
```{r}
# 日次リターンの平均値を計算
mean(daily_stock_return$firm1)
mean(daily_stock_return$firm2)
```
## ファクター型入門(教科書第3.6節)
### 例となるデータフレームの作成
```{r}
# industry列を文字型として定義
firm_ID <- c(1, 2, 3)
name <- c("Firm A", "Firm B", "Firm C")
industry <- c("Machinery", "Chemicals", "Machinery")
# data.frame()関数により三変数のデータフレームを作成
firm_data <- data.frame(firm_ID, name, industry)
print(firm_data) # firm_dataの確認
```
- このように`firm_data`というデータフレームを作成すると,`firm_ID`列は数値型,`name`列と`industry`列が文字型となる.
- しかし,`industry`列は[**カテゴリカル変数**]{style="color: red"}と呼ばれ,各観測データがどのサブカテゴリーに属するかを明らかにする役割を果たしている.
- 性別
- 血液型
- 都道府県
------------------------------------------------------------------------
### ファクター型への変換
```{r}
# industry列をファクター型に変換
firm_data$industry <- as.factor(firm_data$industry)
str(firm_data)
```
- 最初の`as.factor()`関数は,データ列をファクター型に変換する関数.`str()`関数を用いて構造を眺めてみると,`name`列が文字型 (`chr`)のままであるのに対し,`industry`列は[**ファクター型 (`Factor`)に変換済**]{style="color: blue"}.
- ここで,`"Chemicals"`と`"Machinery"`は水準 (`level`)と呼ばれ,各カテゴリーの名前を表す.[**コンピュータ内部では各カテゴリーが自然数**]{style="color: red"}で表されており,今回の観測データはその番号を介して,`2 (Machinery)`,`1 (Chemicals)`,`2 (Machinery)`と表現されている.
- このように文字型でなくファクター型を用いると,自然数で各カテゴリーが表現されるため,任意の順序での並び替えや大小関係の比較が可能となるのがメリットである.
## 今日の講義に入る前の前提知識(教科書第2.1節)
### 会計とファイナンス
- 会計とは,企業の経済活動について,特に投資の現状と成果に着目してそれを要約し,利害関係者に報告するまでのプロセスを指す.したがって,得意とする時間軸は,[**過去と現在**]{style="color: red"}である.
- 一方,ファイナンスの得意とする時間軸は,[**未来**]{style="color: red"}である.何かしらのプロジェクトや資産に投資するということは,現時点で現金を手放す代わりに,将来のキャッシュフローを得ることと言い換えられる.したがって,ファイナンスは,将来期待される投資の成果から,現時点におけるプロジェクトの価値や資産価値を評価するプロセスに焦点を当てる.
- 会計では,投資の成果を収益から費用を差し引いた利益で測るのに対して,ファイナンスではそれをキャッシュフローで測るが,これは両者の目的の違いを反映している.
------------------------------------------------------------------------
### 割引率
- ファイナンスの世界で未来と現在を繋ぐ鍵となるのが,[**割引率**]{style="color: red"} (discount rate)である.
- ここで割引率とは,[**将来キャッシュフローを現在価値に変換する際に用いる値**]{style="color: blue"}のことで,これが分かると,企業金融(コーポレート・ファイナンス)の文脈で投資プロジェクトや企業価値を評価したり,資産運用の文脈でより良いポートフォリオを構築したりするのに役立つ.
------------------------------------------------------------------------
### 現在価値・時間価値
- 例として,確実に1年後に受け取れる100万円(すなわち,確実な1年後のキャッシュフロー100万円)の価値を現時点で評価してみよう.
- 一般に将来発生するキャッシュフローの現時点における価値を[**現在価値**]{style="color: red"} (Present Value; PV)と呼ぶ.「1年後に受け取る100万円」は「現時点の100万円」と異なるので,その現在価値は100万円ではない.
- この違いを[**時間価値**]{style="color:blue"}と呼び,これを定量化するのが割引率の一つ目の役割である.
- 将来キャッシュフローを現在価値に変換することを**「割り引く」**と表現し,現在価値は割り引き後の価値であることを明示的に表現するため,<u>割引現在価値</u>とも言う.
------------------------------------------------------------------------
### 1年後の確実なキャッシュフロー100(万円)の現在価値
- 安全資産(無リスク資産)へと投資したときのリターンを$R_F$で表す.$R_F$は[**無リスク金利**]{style="color: red"} (risk-free rate)と言い,1%や10%というような定数で,投資時点でその値が確定しているのが特徴である[^1].
- 1年後の確実なキャッシュフローを$\mathit{CF}_1$で表すと,その現在価値は,割引率を$R_F$として次のように計算される.
[^1]: 完全に無リスクの資産は存在しないが,実務的には国債金利を無リスク金利のベンチマークとすることが標準的である.
$$
\begin{align*}
\underbrace{\mathit{PV}}_{\textbf{現在価値}}= \frac{\overbrace{CF_1}^{\textbf{1年後の確実なキャッシュフロー}}}{\underbrace{1 + R_{F}}_{\textbf{無リスク金利$R_F$で割り引く}}}
\end{align*}
$$
------------------------------------------------------------------------
### 無リスク金利と現在価値の関係
![](images/fig02_01.png)
------------------------------------------------------------------------
### $T$年後の確実なキャッシュフロー100(万円)の現在価値
- この割引率は1年当たりの値であるので,仮に1年後ではなく$T$年後のキャッシュフローであれば[**その分だけ更に割り引く必要がある**]{style="color: red"}.
$$
\begin{align*}
\underbrace{\mathit{PV}}_{\textbf{現在価値}} &= \frac{\overbrace{CF_T}^{\textbf{$T$年後の確実なキャッシュフロー}}}{\underbrace{(1+R_F)^ {T}}_{\textbf{$T$年分だけ無リスク金利$R_F$で割り引く}}}
\end{align*}
$$
- 次スライドの図では,割引率$R_{F}$を0.1に固定した上で,異なる$T$に対して,確実に受け取れる100万円の現在価値を図示している.$T$が大きいほど,1年当たりの割引率が同じであっても現在価値が小さくなる.
------------------------------------------------------------------------
### キャッシュフローの発生年限と現在価値の関係 {#キャッシュフローの発生年限}
![](images/fig02_02.png)
------------------------------------------------------------------------
## 外部バッケージの導入
### `tidyverse`パッケージとは?
- これまではRの基本パッケージに含まれる関数や演算子のみを利用してきたが,現実のRを用いたデータ分析では,ユーザーが任意に作成した外部パッケージの機能を使うことが多い.
- Rを用いたデータ分析では無くてはならないのが,`tidyverse`と呼ばれるパッケージ群である.以下が,それに含まれる主なパッケージ一覧である.
| 名称 | 使用用途 |
|---------------------------|---------------------------------------------|
| `ggplot2` | グラフの描画によるデータの可視化 |
| `dplyr` | データの加工や操作に便利な関数の提供 |
| `tidyr` | 雑然データを整然データの形式に変換する関数の提供 |
| `readr` | CSVファイルなどの高速,かつ,ユーザー・フレンドリーな読み込み |
| `tibble` | データフレームを改良した`tibble`というデータ形式の提供 |
------------------------------------------------------------------------
### `tidyverse`パッケージのインストール
```{r eval=FALSE}
# tidyverseのインストール - 通常バージョン
install.packages("tidyverse")
```
- 外部パッケージのインストール方法は何通りかあるが,[**CRAN**]{style="color: red"} (The Comprehensive R Archive Network: [cran.r-project.org](https://cran.r-project.org/))というWebサイトからダウンロードするのが最も簡単である.
- 基本パッケージに含まれる`install.packages()`関数を用いて,第一引数にインストールしたいパッケージ名を`""`で囲って指定する.
------------------------------------------------------------------------
### `ggplot2`による作図 --- 作図データの準備
::: {.callout-note icon="false"}
#### 目標
$R_{F}$が0.1から0.01刻みで0.2まで変化するときの1年後の確実なキャッシュフロー100の現在価値を求め,割引率に応じて現在価値がどのように変化するか可視化してみよう.
:::
```{r}
# 11次元の無リスク金利ベクトルの作成
R <- seq(0.1, 0.2, 0.01) # 無リスク金利ベクトルRを作成
```
- `100`というのは1次元のスカラー(一つの実数)であり,`R`は11次元のベクトルである.したがって,次式を計算しようとすると,両者の次元が一致しておらず,数学的には不完全な式となっている. $$
PV = \frac{\overbrace{100}^{\textbf{スカラー}}}{1 + \underbrace{\text{R}}_{\textbf{11次元のベクトル}}}
$$
------------------------------------------------------------------------
### ブロードキャスティング
- R言語は[**ブロードキャスティング**]{style="color: red"} (broadcasting)といって,片方の次元を整数倍して次元を自動的に揃える機能を持つ.
![ブロードキャスティングのイメージ](images/Fch03_05.png){width="50%"}
```{r}
# ブロードキャスティングによるPVの計算
PV <- 100 / (1 + R)
```
------------------------------------------------------------------------
### `ggplot2`による作図 --- データフレームの準備
- `ggplot2`は,[**入力データをデータフレームの形式**]{style="color: blue"}で準備する必要があるので,まずは`data.frame()`関数を使って 新たなデータフレーム`figure_data`を作成しよう.
```{r}
# データフレームの作成
figure_data = data.frame(R, PV) # 計算結果をデータフレームに格納
```
### `ggplot2`による作図 --- `tidyverse`パッケージの読み込み
- `ggplot2`パッケージを使うためには,`library()`関数を使って`tidyverse`を利用することを冒頭で宣言する必要がある.
- ただし,本講義では,第1回で学習したように,各パッケージがインストール済みか否かにかかわらず,パッケージのインストール $\rightarrow$ 読み込みまで済ますことを目的として,`pacman::p_load()`を利用する.
```{r}
# ggplot2による作図
pacman::p_load(tidyverse) # 本講義のやり方
```
::: callout-tip
### `ggplot2`の`gg`とは
[**grammar of graphics**]{style="color: blue"}の略である.`ggplot2`では,グラフの構成要素を各種のレイヤーに分解し,コード上でそれを積み重ねていく形でグラフを作図する.
:::
------------------------------------------------------------------------
### `ggplot2`による作図 --- `data`引数の指定
- 次は,`ggplot()`関数により,作図用キャンバスを準備し,入力データを指定.
- 引数では`data = figure_data`として,`figure_data`を入力用データとして用いることを宣言している.
```{r}
# ggplot2による作図
pacman::p_load(tidyverse)
ggplot(data = figure_data) # data引数により入力データを指定
```
- あとは,[**`+`演算子を用いてレイヤーを足していく形で図を作成**]{style="color: red"}する.
- グラフの中心となる折れ線グラフを追加しているのが,`geom_line()`関数である.
- `mapping`引数の`aes()`関数では,$x$軸と$y$軸の要素をラベル名で指定している.
```{r}
# ggplot2による作図
pacman::p_load(tidyverse)
ggplot(data = figure_data) +
geom_line(mapping = aes(x = R, y = PV)) # 折れ線グラフを書く
```
------------------------------------------------------------------------
### `ggplot2`による作図 --- 散布図の追加
- `ggplot2`の使い方に慣れるために,先ほどの折れ線グラフに各データを表す点を追加してみよう.
- 散布図を追加する関数は`geom_point()`であるから,`+`演算子を用いてそれを先ほどのコードに追加すると,散布図が上書きされる.
```{r}
pacman::p_load(tidyverse)
ggplot(data = figure_data) +
geom_line(mapping = aes(x = R, y = PV)) +
geom_point(mapping = aes(x = R, y = PV)) # 点グラフを追加
```
------------------------------------------------------------------------
### `ggplot2`による作図 --- その他の調整
- 続いて,グラフの見栄えを微調整しよう.まず,$x$軸と$y$軸のラベルをそれぞれ`Discount Rate`と`Present Value`へと変更しよう.
- ラベルの変更は,`labs()`関数を使えば簡単にできる.
```{r}
pacman::p_load(tidyverse)
ggplot(data = figure_data) +
geom_line(mapping = aes(x = R, y = PV)) +
geom_point(mapping = aes(x = R, y = PV)) +
labs(x = "Discount Rate", y = "Present Value") + # labs()関数でラベル指定
theme_classic() # 全体的な体裁(テーマ)を設定
```
- 最後に加えた`theme_classic()`関数は,グラフの背景や枠線など(グラフのテーマと言う)を統一的に変更するための関数である.
- グラフのテーマは他にも多数用意されており,枠線を無くす`theme_void()`や,背景は白だがメモリを表す十字線が入る`theme_bw()`など,複数の選択肢があるので,目的に応じて使い分けると良いだろう.
------------------------------------------------------------------------
### 練習問題
::: {.callout-note icon="false"}
#### Exercise 1
- [キャッシュフローの発生年限と現在価値の関係](#キャッシュフローの発生年限)で掲示されている図を各種の関数と`ggplot2`を駆使して描画せよ.なお,$x$軸のラベルは`year`,$y$軸のラベルは`Present Value`とすること.
:::