在 STATA 批次讀入檔案
分析的資料有時候會被切成許多小檔案,比如說:不同年份、地區,我們常需要將這些小檔案批次讀取、整理並合併,以進行分析。合併檔案的指令可以參考 3–1 的 merge
、 append
,但這節想要討論的是:如何寫一小段精簡、好讀的指令來讀取、合併一堆小檔案。
批次讀檔
檔名有規律時
如果小檔案的名稱有既定的格式的話(比如說:data01、data02…data12),那麼我們可以 輕易地利用 loop 來讀取並合併檔案。Fig 5-1 展示了一個例子,其中假設要讀取的小檔案名稱有「YYYYMM.dta」的形式(如:201501.dta),我設了 year、month 兩層 loop,透過 local 來儲存 YYYYMM 並藉此讀取檔案。¹之後我們對每一份讀入的小檔案進行簡單的清理並暫存成「乾淨的」小檔案,最後再合併成一份大檔案(Appending 的部分,除了 use 第一筆外(if `t'==201501
),其他都是 append 到現有檔案上 )。
檔名無規律時
當小檔案的名稱沒有既定格式時(比如說一堆代表地名或公司名稱的字串),這時候我們可以嘗試建立一個收集所有檔名的 list 或文件,然後再依照 list 或文件讀取檔案。首先,我們可以利用 DOS/Unix 指令建立這樣的文件。在 STATA 中,我們可以在 command 最前方加上 !
來使用 DOS/Unix 指令。比如說(以 macOS 為例):!ls
可以列出目前工作路徑上的所有檔案,或是 !ls *.dta
可以列出所有以 .dta 結尾的檔案。Fig 5-2 提供了一個例 子,以下條列說明:
!*.csv > ”filelist.txt”
,建立了一份名為 filelist 的.txt 檔,並且逐行儲存路徑內以.csv 結尾之檔案名稱。file open <handle> <file>, read
,在 STATA 內讀入文件(有別於 STATA 讀入資料)。讀入的檔案名稱在 STATA 內稱為<handle>
(Fig 5-2的myfile
)。file read <handle> line
會逐行讀文件中的文字並暫存成line
這個 local 變數。我們可以藉由這個 local 變數去讀取小檔案。file read
讀到最後時,就不會再指定任何東西給 line 這個 local 變數了。每使用一 次 ,我們可以查看r(eof)
(seereturn list
),檢查是否已經讀到文件最後一行 了。- 因此,Fig 5-2 利用了 while 迴圈:不斷地利用文件中逐行儲存的檔名讀取檔案, 處理後合併到一開始儲存的 append_file,直到
r(eof)==1
為止,也就是讀到了 end of file。 - file close <handle> 會將現在讀取的文件關閉。
最後,我們在合併時也許會希望有個變數註明小檔案的來源(年度、地區等)。我們可以在 append 前生成一個變數儲存檔名,若我們所需要的資訊只是檔名的一部分,這時候可以再利用字串函式或正規表達式等工具處理。²
[1]: 注意,我是使用 local <local var>=<exp>
,因此 local 儲存的是 201501
。拿掉 =
的話,local 儲存的就會變成 ”2015*100+1”
的字串。
[2]: 本節參考自 https://stats.idre.ucla.edu/stata/faq/how-can-i-combine-a-large-number-of-files/