Sitting in an Armchair

取るに足らない勉強日記

【R】Stataのデータ (.dta) ファイルをRで開くときの3つのやり方

要約:古くても有能。

概要

dtaファイルはStata用のデータフォーマットです。たまにオープンデータがdta形式でしか公開されていないことがありますが、そんなときにRで読み込む方法を忘れないように書いておきます。

3つの方法

dtaファイルを読み込む関数を提供しているパッケージは主に3つあります。

  • foreignパッケージ:read.dta
  • readstata13パッケージ:read.dta13
  • havenパッケージ:read_dta

foreign::read.dta()

foreignパッケージはStataのほかに、SAS, SPSS, Minitabなどの様々なフォーマットのデータ読み込みの関数を用意しています。
(参考:CRAN - Package foreign

一方で、2020年3月末時点(バージン0.8-76)のパッケージ説明書にはStata 5-12のフォーマット以外は今後もサポートする予定がないとの記載があります。新しいデータを読み込む際は他の2手法しか使えないかも。

Description
Reads a file in Stata version 5–12 binary format into a data frame. Frozen: will not support Stata formats after 12.
(引用:https://cran.r-project.org/web/packages/foreign/foreign.pdf

library(foreign)
read.dta("hoge.dta")

readstata13:read.dta13()

foreignパッケージがStata 13以降のファイルに対応していないということで新たに作られたパッケージです。dtaファイルにのみ使えます。
(参考:readstata13 package | R Documentation
とはいえStata 13にしか使えないということはなく、2020年3月末時点(バージン0.9.2)ではStata 15より古いものなら読めるようです。

library(readstata13)
read.dta13("hoge.dta")

haven::read_dta()

havenはtidyverse族の一味で、SAS, SPSS, Stataのデータ読み込み・書き出しを可能にしています。
RStudioで[File]->[Import Dataset]->[From Stata]と選択したときに利用されるのもこの関数です。
haven.tidyverse.org

library(haven)
read_dta("hoge.dta")

速度比較

利便性としてはStataのバージョン・他言語とも幅広く対応しているhavenパッケージに分がある感じです。
ここからは、データを読み込むときの速度も比較してみます。

環境
> packageVersion("foreign")
[1]0.8.71’
> packageVersion("readstata13")
[1]0.9.2’
> packageVersion("haven")
[1]2.2.0’
Stata 12以前のデータを読んでみる(比較的小さいデータ)

まずは小さなデータでやってみようと思います。データはWooldridge "Introductory Econometrics" のオープンデータ countymurders.dtaを使ってみます*1。20変数×obs37349、約2.5MBのデータです。

countymurders.dtaの読み込み時間分布
countymurders.dtaの読み込み時間。100回読んで分布を比較しています

なんか昆布みたいな図ですね。
ご覧の通り、古いデータであればforeign::read.dta関数が圧倒的に早いです。とはいえ、どの関数もだいたい2.5MBのデータを読み込むのに0.2秒を超えることはあまりないので、実用上はそこまで差はないのかもしれません。

Stata 12以前のデータを読んでみる(大きいデータ)

大きいデータとして、例えば米国の国勢調査局が「所得と政策参加調査」(Survey of Income and Program Participation: SIPP)のパネルデータを公開しています。2014年以降のデータはStataファイルでも公開されるようになりました。(Survey of Income and Program Participation (SIPP)
このデータで同様の検証をしてみようと思ったのですが、データ全体で大体20GBくらいあるということで単純計算でも最低30分はかかります。あまりにも時間がかかりすぎるんでいったん断念しました。後日更新予定です。
これくらい大きいデータになってくると、小さいデータの0.01秒が顕著な差になって表れてきそうです。

Stata 13以降のデータを読んでみる

とりあえず手元にあった、小さめのデータでやってみます。データはWooldridge "Introductory Econometrics" のオープンデータ school93_98.dtaを使ってみます*2。18変数×obs10668、約500KBのデータです。

Stata 13以降のデータなので、read.dta()を使ってみるとエラーが出ます。

> read.dta("school93_98.dta")
Error in read.dta("school93_98.dta") : not a Stata version 5-12 .dta file

というわけで、read_dtaとread.dta13のみの比較になりますが、

school93_98.dtaの読み込み時間
school93_98.dtaの読み込み時間。100回読んで分布を比較しています。

データが小さすぎて微妙な違いしかないですね…。でも平均的にはhavenのほうが速そうです。大きいデータでは顕著な差になりそうな気もします。
新しいStataフォーマットのデータで大きいものがあったら同様の検証をしてみようと思います。

検証まとめ

利便性と速さに関しては、形式があっていれば爆速で読み込めるforeign::read.dta()、速さはそこそこだがどんなケースでも大体使いやすいhaven::read_dta()という感じでしょうか。readstata13はhavenの下位互換といった感じです。

関数 読み込みの速さ バージョン対応 他形式のデータへの利用
haven::read_dta()
readstata13::read.dta13 ×
foreign::read.dta ×

とりあえずforeignを使ってみて、エラーが出たらhavenでやってみるというのがベストかもしれません。
一番古いのが有能というちょっと意外な結果でした。

補足:グラフ作成のコード

Gistを初めて使ってみました。結構簡単なんですねえ

*1:Book Companion Siteよりインストール

*2:インストール先はcountymurders.dtaと同じ。