RでEDINETから財務データを入手・分析する~⑤前処理編2/3~
記事一覧
はじめに
本記事は前処理編1/3の続きであり、5番目の記事にあたる。本記事で行う作業は、xbrlファイルからのデータ抽出のために必要な機能を補助関数として定義することである。
また、本ブログの執筆に際してこちらの記事を参考にさせていただいた。
本記事の概説
実際の整頓の流れの解説は次の記事に回す。本記事では8つの補助関数を定義しているが、それぞれをどうやって使うかを理解する必要はまだない。それぞれの関数がどんな機能を持って、何をアウトプットするのかが分かれば十分である。
参考記事との比較
参考にさせていただいたこちらの記事との大きな差異は、必要な機能を補助関数として分けたことと、xbrlDoAll()
を使っていないことである。前者はコードの可読性とメンテナンスの容易さに資する。xbrlDoAll()
は、xbrlファイルを指定すればその中にある情報(factやcontextIdなど)をdata.frameのlistとしてまとめて出してくれる便利な関数であるが、参考先にもある通り1企業あたり1分以上の時間がかかる。
本ブログではlow-level functionを用いて、処理のボトルネックである部分を独立させて1回のみ実行することによって、1企業あたりの整理にかかる時間を1~4秒に短縮した。ただし、筆者はxbrlデータの仕組みについて十分熟知しておらず、また本記事の処理は試行錯誤の結果から導いたものであるため、加工されたデータの網羅性、正確性については一切保証できない。
XBRL
packageのリファレンスマニュアルはこちらである。
Rによる実装
概説で述べた通り、以下の関数群をどうやって使うかはまだ理解不要である。それぞれ何をしたいのかが分かれば次回の記事の理解がスムーズとなる。
get_docID()
解凍したzipファイルのdocIDを取得する関数である。抽出後のデータを"docID.csv"としてtidyupフォルダに保存するために必要となる。インプットはzipファイルのpathと、zipフォルダのpathである。アウトプットにはdocIDを返す。
get_docID <- function(zip, path_zip){ zip %>% str_remove(pattern = path_zip) %>% str_remove(pattern = "/") %>% str_remove(pattern = ".zip") %>% return() }
get_fact()
xbrlファイルからfactを含むdata.frameを抽出する関数である。流れは
となっている。インプットはxbrlファイルへのpathであり、アウトプットはfact情報を含むdata.frameである。
get_fact <- function(path_xbrl){ parsed <- xbrlParse(path_xbrl) fact <- xbrlProcessFacts(parsed) xbrlFree(parsed) ## fact %>% as_tibble() %>% mutate_at("fact", str_conv, encoding = "UTF-8") %>% mutate_if(is.factor, as.character) %>% return() }
get_context()
get_fact()
と同様。contextIdの入手のために必要である。
get_context <- function(path_xbrl){ parsed <- xbrlParse(path_xbrl) context <- xbrlProcessContexts(parsed) xbrlFree(parsed) context %>% as_tibble() %>% mutate_if(is.factor, as.character) %>% return() }
get_definition()
基本的にget_fact()
と同様。roleIdの入手のために必要である。definition情報はxbrlファイルではなくxmlファイルに入っているため、その辺りを修正している。ただし統一化のために、インプットはget_fact()
と同様、xbrlファイルへのpathとしている。アウトプットはroleIdを含むdata.frameである。
get_definition <- function(path_xbrl, fs_name){ path_pubdoc <- dirname(path_xbrl) path_def <- dir(path_pubdoc, full.names = TRUE) %>% str_subset(pattern = "def.xml$") %>% str_subset(pattern = "ifrs", negate = TRUE) parsed_def <- xbrlParse(path_def) definition <- xbrlProcessArcs(parsed_def, arcType = "definition") xbrlFree(parsed_def) definition %>% as_tibble() %>% mutate_all(as.character) %>% rename("elementId" = toElementId) %>% slice(str_which(.$roleId, str_c(fs_name, collapse = "|"))) %>% slice(str_which(.$roleId, "jppfs")) %>% select(elementId, roleId) %>% return() }
get_ac_standard()
採用している会計基準を返す関数である。インプットにはget_fact()
で取得したdata.frameを用いる。アウトプットは
のいずれかを想定している*2。
get_ac_standard <- function(joined_fact){ joined_fact %>% slice(str_which(.$elementId, "AccountingStandardsDEI")) %>% purrr::pluck("fact") %>% return() }
join_fcl()
fact、context, labelStringをそれぞれ含むdata.frameをjoinする関数である。他の関数より定義する必要性は薄いが、次回の記事における統合関数のコードをすっきりさせるために定義した。
join_fcl <- function(joined_fact, joined_context, label){ joined_fact %>% left_join(joined_context, by = "contextId") %>% left_join(label, by = "elementId") %>% return() }
is_consolidated()
「連結財務諸表の情報をもつ行数」を返す関数である。連結財務諸表作成企業であれば1以上(TRUE)の値をとり、そうでなければ0(FALSE)を返す*3。インプットはjoin_fcl()
でjoinしたdata.frameである。
is_consolidated <- function(joined_fcl){ joined_fcl %>% slice(str_which(.$elementId, "jppfs")) %>% slice(str_which(.$contextId, "NonConsolidated", negate = T)) %>% nrow() %>% return() }
tidy_joined_data()
最終的に結合されたdata.frameの調整をする関数である。調整内容は
である。
tidy_joined_data <- function(joined_data){ joined_data %>% select(labelString, fact, startDate, endDate, elementId, contextId, roleId) %>% mutate_at("elementId", str_remove, pattern = "jppfs_cor_") %>% separate(col = roleId, into = c("garbage", "roleId"), sep = "rol_") %>% select(-garbage) %>% mutate(roleId = if_else(is.na(.$roleId) & str_detect(.$elementId, "SGA"), true = "StatementOfIncome", false = .$roleId)) %>% return() }
おわりに
次回の記事では、前記事及び本記事の内容を統合した関数を定義し、その実行によって実際にzipファイルを分析可能な形に整頓していく。