【R】 財務分析を手助けする {XBRL} パッケージを紹介しようと思う

# 1. 概要

企業のビジネスレポート（有価証券報告書）の分析に際して、XBRLファイルをRで処理するためのパッケージ`{XBRL}`の存在をご存じでしょうか。
かくいう僕も、昨日ネットサーフィンしているうちに『へぇ～～こんなパッケージがCRANにあるんだぁ～～』と知ってから見様見真似で弄ってみました。英弱Rerには少々厳しい部分もありましたが、日本語のレファレンスが皆無だったので分かった範囲で書いておきます。

# 2. 導入
CRANにあります。

```R
install.packages("XBRL")
```

# 3. {XBRL}とは

`{XBRL}`パッケージは、**.XBRLファイル形式のビジネスレポートをリスト型データに変換してくれるツールです。**

このパッケージの特徴（であり難解な部分）は、XBRLの解析に際してのアプローチが以下の3つ用意されている点ですが、**いずれのアプローチによっても（究極的には）同じデータを出力できます。**

- 低水準関数による処理アプローチ
- オブジェクト指向に近い処理アプローチ
- 一般的なRらしい処理アプローチ

以下の3-1. から3-3. で各アプローチについて記載しておきますので、お好みの方法でXBRLファイルを分析してみてください。
下に行けば行くほど操作が簡単になりますが、処理時間が長くなります。

## 3-1. 低水準関数による処理

C言語とかに精通している人であれば理解しやすい方法じゃないでしょうか。僕は一度も触れたことないですけど・・・。

低水準関数を用いた処理の流れは、次の通りです。

- XBRLファイルを読み込み、ファイルポインタとして宣言する。その情報をオブジェクトとして保管する。
- 分析したい内容につき、保管したポインタオブジェクトを`doc`引数として渡して分析する。
- 分析完了次第、ファイルポインタを削除する

普通のRerにとって、『ポインタってなんだ？』という感じ（僕もそう）かもしれないです。
ざっくり言えば、XBRLファイルをメモリから参照可能な状態にしておくこと、くらいの理解です。間違ってたらごめんなさい。

### 実践

```R
library(XBRL)
doc <- xbrlParse("hoge.xbrl") # ポインタを宣言

# .XBRLファイルには、以下の関数が使用可能です。
# xbrlProcessContexts(doc) コンテクスト（事業体、年など）に関する情報。
# xbrlProcessFacts(doc) ファクト（財務数値など）に関する情報。
# xbrlProcessUnits(doc) ユニット（貨幣単位）に関する情報。
# xbrlProcessFootnotes(doc) 脚注に関する情報。いわゆる注記とは別物。

fct <- xbrlProcessFacts(doc) # factに関するlist型データを取得

# ポインタを削除
xbrlFree(doc)

# data.frameへ変換
fct <- as.data.frame(fct, stringsAsFactors = FALSE)



# ここ以降は、3つの方法いずれも共通の内容です。



# 環境によっては文字化けするので、文字コードの変換が必要になります。
fct <- data.frame(lapply(fct, iconv, from="utf-8", to="shift-jis"))

# filterで必要な情報を取得
# Factsの場合、財務数値等のコンテンツは4行目のfactに記載されているので、
# dplyr::filterでelementIdやcontextIdを絞り込んだ後、
# dplyr::selectで必要な情報を抽出します。

# e.g.1 今年度の経常収益の抽出
ordIncome <- (filter(fct, elementId == "jpcrp_cor_OrdinaryIncomeSummaryOfBusinessResults",
                   contextId == "CurrentYearDuration") %>% 
              select(., "fact"))[1,1] %>% 
  as.character() %>%
  as.numeric()
# 桁数が多いと指数表記になってしまうのを回避
options(scipen=100)
ordIncome

[1] 50353000000



# e.g.2 書類名の抽出
docname <- (filter(fct, elementId == "jpcrp_cor_DocumentTitleCoverPage",
                   contextId == "FilingDateInstant") %>% 
              select(., "fact"))[1,1] %>% 
  as.character()
docname

[1] "有価証券報告書"

```

## 3-2. オブジェクト指向に近い処理

この方法は、データと関数（メソッド）をまとめたオブジェクトを作って操作していこうという、Rでは珍しくオブジェクト指向を地で行くものです。ポイントなんて知らなくても操作できる点において難易度は先ほどより下がり、かつ処理速度は先ほどの方法に比べても正直そんなに変わらないと思います。

ここで使う`XBRL()`関数の公式の説明はこう書いてあります。
> "Mutable state" function that exposes "methods" that analyze an XBRL
instance an its associated DTS.

『XBRLとその関連ファイルを分析するためのメソッドを表示するミュータブルな状態の関数』（超意訳）ということなんですが、これをオブジェクトに代入することでメソッドのように動く、らしいです。

### 実践

```R
library(XBRL)

# オブジェクトに関数のリスト（≒メソッド）を代入
xbrl <- XBRL()

# 予めfactor型を回避する
options(stringsAsFactors = FALSE)

# XBRLファイルの読み込み
xbrl$openInstance("hoge.xbrl")

# XBRLファイルの分析
# 必要ないものは省略してOK
xbrl$processContexts()
xbrl$processUnits()
xbrl$processFacts()
xbrl$processFootnotes()

# 読み込んだ元データ（XBRLファイル）をRから破棄
xbrl$closeInstance()

# 分析結果の書き出し
# リスト型データが出力される
xbrl.dataset<- xbrl$getResults()

# ここから必要な情報へ絞り込む
# 財務情報等が必要であれば、fact成分を抽出する。
fct <- as.data.frame(xbrl.dataset$fact, stringsAsFactors = FALSE)


# 当年度の経常利益の抽出
# ここ以降の解説は、3-1. のコードを参照してください。
fct <- data.frame(lapply(fct, iconv, from="utf-8", to="shift-jis"))
library(dplyr)
ordIncome <- (filter(fct, elementId == "jpcrp_cor_OrdinaryIncomeSummaryOfBusinessResults",
                   contextId == "CurrentYearDuration") %>% 
              select(., "fact"))[1,1] %>% 
  as.character() %>%
  as.numeric()
options(scipen=100)
ordIncome

[1] 50353000000

```

## 3-3. 一番お手軽で簡単な処理

この方法は、XBRLのファイルパスを引数に渡すだけで下処理を全部の作業をやってくれます。超簡単。
ただし、幾つかデメリットがあります。

- XBRLファイル単体での分析は不可能で、XMLファイル等、有報のZIPの中身を一式揃えておかなければならない。そのため、ソースファイルがめちゃくちゃ重くなる。
- XBRL以外の周辺ファイルも分析の対象になる。そのため、必要以上の部分も分析のプロセスにかけられてしまうため、一枚の有報でもかなり時間がかかる。

なので、可能であれば既に紹介した方法のいずれかを使うことをおすすめします。
一方で、上記2つの方法が難しいと感じたら、多少時間は掛かっても以下で紹介する方法に委ねてもよいと思います。

### 実践

```R
library(XBRL)
xbrl.dataset <- xbrlDoAll("hoge.xbrl")

# これでOK。あとは方法2と同じです。

# リストからfact成分を取り出してdata.frameに変換したら完了です。
fct <- as.data.frame(xbrl.dataset$fact, stringsAsFactors = FALSE)

# 当年度の経常利益の抽出
# ここ以降の解説は、3-1. のコードを参照してください。

fct <- data.frame(lapply(fct, iconv, from="utf-8", to="shift-jis"))
library(dplyr)
ordIncome <- (filter(fct, elementId == "jpcrp_cor_OrdinaryIncomeSummaryOfBusinessResults",
                   contextId == "CurrentYearDuration") %>% 
              select(., "fact"))[1,1] %>% 
  as.character() %>%
  as.numeric()
options(scipen=100)
ordIncome

[1] 50353000000

```

# 4. 補足

## 4-1. elementIdについて

elementIdはXML文書やXBRL文書でいう「名前空間」と「要素名」の組み合わせですが、このパッケージ`{XBRL}`ではコロン`:`ではなくアンダーバー`_`で繋ぐ点で少し記法が違うので注意しましょう。

```R
# こうではなく
elementId == "jpcrp_cor:OrdinaryIncomeSummaryOfBusinessResults"

# こう書く
elementId == "jpcrp_cor_OrdinaryIncomeSummaryOfBusinessResults"
```

参考: [よく分からないXBRLをざっくり理解したい男たち!! - Qiita](https://qiita.com/zakkiiii/items/d2dac59eb4447f36f0e6#3-2-3-%E6%AC%B2%E3%81%97%E3%81%84%E8%A6%81%E7%B4%A0%E3%81%AF%E3%81%A9%E3%81%93%E3%81%AB%E3%81%82%E3%82%8B)

## 4-2. contextIdについて

こちらはcontextRef属性と同じです。記法も変わらないので、何ぞやという方はこちらを参考にしてください。

[【R】 XBRLから財務諸表項目を吸い上げる - Qiita](https://qiita.com/zakkiiii/items/21ac1bac9ec76142a7bd#4-3-1-2-2-contextref%E5%B1%9E%E6%80%A7)

# 5. おわりに

率直に、仕様を理解するのが難しかったです。
実際に触って理解するのが一番良いと思います。

.XBRLファイルは`{xml2}`で取り扱う方法[^1]もありましたが、数値情報だけ拾うなら`{XBRL}`はかなり優秀だと思います。
逆に注記や非財務情報の抽出には、そもそもXBRL自体がそこまでを想定して設計されているとは言えないので、従来通り`{xml2}`で引き抜くのがよいでしょう。

というわけで、`{XBRL}`と`{xml2}`を上手く使い分けましょう。

Enjoy!

おしまい。

# 6. 参考文献

- https://cran.r-project.org/web/packages/XBRL/index.html
- https://cran.r-project.org/web/packages/XBRL/XBRL.pdf

[^1]: [【R】 XBRLから財務諸表項目を吸い上げる - Qiita](https://qiita.com/zakkiiii/items/21ac1bac9ec76142a7bd)