在 STATA 批次讀入檔案

CW Wayne Yeh
4 min readSep 21, 2021

--

分析的資料有時候會被切成許多小檔案,比如說:不同年份、地區,我們常需要將這些小檔案批次讀取、整理並合併,以進行分析。合併檔案的指令可以參考 3–1 的 mergeappend ,但這節想要討論的是:如何寫一小段精簡、好讀的指令來讀取、合併一堆小檔案。

批次讀檔

檔名有規律時

STATA 批次讀檔 (1)
Fig 5–1 STATA 批次讀檔 (1)

如果小檔案的名稱有既定的格式的話(比如說:data01、data02…data12),那麼我們可以 輕易地利用 loop 來讀取並合併檔案。Fig 5-1 展示了一個例子,其中假設要讀取的小檔案名稱有「YYYYMM.dta」的形式(如:201501.dta),我設了 year、month 兩層 loop,透過 local 來儲存 YYYYMM 並藉此讀取檔案。¹之後我們對每一份讀入的小檔案進行簡單的清理並暫存成「乾淨的」小檔案,最後再合併成一份大檔案(Appending 的部分,除了 use 第一筆外(if `t'==201501 ),其他都是 append 到現有檔案上 )。

檔名無規律時

STATA 批次讀檔 (2)
Fig 5–2 STATA 批次讀檔 (2)

當小檔案的名稱沒有既定格式時(比如說一堆代表地名或公司名稱的字串),這時候我們可以嘗試建立一個收集所有檔名的 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)(see return 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/

--

--

CW Wayne Yeh

資料分析/閱讀筆記/生活雜感。我是葉政維,台大經研畢,目前是樹鋸分析師🪚,正在職場站穩腳步,也在探索什麼是好的生活。