PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維...

29
Practical Stata notes 葉政維 NTU Econ 2018 9 13 在開始本筆記之前,我想先做個簡單的⾃我介紹和寫作動機。本⼈是⽬前就讀台⼤ 經濟碩班的學⽣,葉政維。接觸 Stata 已經將近 3 年,也將 Stata 利⽤在研究上。Stata ⼀款非常容易上⼿的統計軟體,即使對於有程式基礎的⼈,Stata 也是⽤來完成實證研究 的好⼯具之⼀。然⽽,要能適當地運⽤於研究或任何的專案上,卻也需要⼀些經驗。本 ⼈不敢說是 Stata 的專家,但也⾃認對於基本功能熟悉,也累積了⼀些經驗,因此好⽍也 算是⼀隻善於剝香蕉的猴⼦。本筆記正是本⼈學習 Stata 的⼀些經驗整理。雖說網路上可 能有許多更詳細的 Stata 教學,但我會試著以精簡、消化過的⽅式呈現,並適時強調⼀ 些重要的做法與觀念,尤其是在研究上的應⽤。倘若這些經驗 (也就是本筆記),能加速 Stata 的學習,抑或讓⼈更順暢地應⽤ Stata 於往後的研究,這會是令我開⼼的⼩貢獻。 這個筆記並不預設讀者接觸過統計軟體或是程式語⾔,也不預設讀者處理過任何資 料。筆記內⽂會盡可能的簡潔 (正如 Stata code 的風格),介紹的指令也會盡量聚焦於常 ⽤與實⽤的那些。如果想深入了解每個指令還有哪些選項、參數可以調整,非常建議可 以再去參考 Stata 的「help file」。本筆記希望能作為⼀個「引路⽯」,也儘可能提供⼀個 「概略但全⾯」的導覽。筆記的組織如下:第⼀節會進⾏⼀些初步的介紹,包括 Stata 的介 ⾯、基本的語法結構等;第⼆節則介紹⼀些基本的 Stata 指令,這邊的指令⼤多會和探索 資料與簡單的操作資料有關;第三章會進⼀步談到更多操作資料相關的指令,以及談到 Stata 上清理資料的例⼦;第四章會談到使⽤ Stata 做⼀些簡單的統計與計量分析;(下的章節預計討論繪圖、特殊資料格式的操作、隨機與模擬等)以下是⼀些⾏⽂說明: • Stata code highlight 標⽰,如: reg grade study_hard 指令下的引數 (arguement) <my arg> 標⽰。 • Stata code ⼤多可以縮寫,因此本筆記⼤多呈現縮寫。必要時我會寫出 command 名並以底線標註縮寫。 指令中... 最後,感謝... 的幫忙。 1

Transcript of PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維...

Page 1: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Practical Stata notes

葉政維

NTU Econ

2018 9 13

在開始本筆記之前,我想先做個簡單的⾃我介紹和寫作動機。本⼈是⽬前就讀台⼤

經濟碩班的學⽣,葉政維。接觸 Stata已經將近 3年,也將 Stata利⽤在研究上。Stata是⼀款非常容易上⼿的統計軟體,即使對於有程式基礎的⼈,Stata也是⽤來完成實證研究的好⼯具之⼀。然⽽,要能適當地運⽤於研究或任何的專案上,卻也需要⼀些經驗。本

⼈不敢說是 Stata的專家,但也⾃認對於基本功能熟悉,也累積了⼀些經驗,因此好⽍也算是⼀隻善於剝香蕉的猴⼦。本筆記正是本⼈學習 Stata的⼀些經驗整理。雖說網路上可能有許多更詳細的 Stata教學,但我會試著以精簡、消化過的⽅式呈現,並適時強調⼀些重要的做法與觀念,尤其是在研究上的應⽤。倘若這些經驗 (也就是本筆記),能加速Stata的學習,抑或讓⼈更順暢地應⽤ Stata於往後的研究,這會是令我開⼼的⼩貢獻。

這個筆記並不預設讀者接觸過統計軟體或是程式語⾔,也不預設讀者處理過任何資

料。筆記內⽂會盡可能的簡潔 (正如 Stata code的風格),介紹的指令也會盡量聚焦於常⽤與實⽤的那些。如果想深入了解每個指令還有哪些選項、參數可以調整,非常建議可

以再去參考 Stata的「help file」。本筆記希望能作為⼀個「引路⽯」,也儘可能提供⼀個「概略但全⾯」的導覽。筆記的組織如下:第⼀節會進⾏⼀些初步的介紹,包括 Stata的介⾯、基本的語法結構等;第⼆節則介紹⼀些基本的 Stata指令,這邊的指令⼤多會和探索資料與簡單的操作資料有關;第三章會進⼀步談到更多操作資料相關的指令,以及談到

在 Stata上清理資料的例⼦;第四章會談到使⽤ Stata做⼀些簡單的統計與計量分析;(剩下的章節預計討論繪圖、特殊資料格式的操作、隨機與模擬等)。

以下是⼀些⾏⽂說明:

• Stata code以 highlight標⽰,如: reg grade study_hard

• 指令下的引數 (arguement)以 <my arg>標⽰。

• Stata code⼤多可以縮寫,因此本筆記⼤多呈現縮寫。必要時我會寫出 command全名並以底線標註縮寫。

• 指令中...

最後,感謝...的幫忙。

1

Page 2: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Contents

1 INTRODUCTION 3

1.1 Stata and Other Statistic Software . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.2 Interface and Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.3 Stata and Related Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.4 Reference and Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 BASIC 7

2.1 Import/Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.2 Data Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.3 Arithmetic Manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

2.4 Logics and Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

2.5 Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.6 Label and Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2.7 By Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.8 Local Variable and Return List . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

2.9 Plotting, String Function and Miscellanea . . . . . . . . . . . . . . . . . . . . . 17

3 DATAWRANGLING 21

3.1 Combining Dataset, Append and Merge . . . . . . . . . . . . . . . . . . . . . . 21

3.2 Aggregate and Reshape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.3 Duplicate and Missing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

4 Stata FOR ECONOMETRIC 28

4.1 Linear Regression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.2 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

2

Page 3: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig1-1 Code Comparison

1 INTRODUCTION本節會從 Stata本⾝的介紹談起,接著簡介 Stata的介⾯,最後說明 Stata相關的檔案類型。讀者需要先確認 Stata是否正確安裝且使⽤ 14.0以上的版本。

1.1 Stata and Other Statistic Software

Stata 是⼀個商⽤統計軟體,同時⽀援圖形化介⾯ (GUI) 與程式指令。也許讀者有使⽤Excel處理資料,或是聽說過其他統計軟體與程式語⾔,像是 SPSS、SAS、R等。那麼為何我們要⽤ Stata呢?

⾸先,不論利⽤何種⼯具進⾏實證研究,經常都需要有⼀個腳本 (script)把所有流程給記錄下來。這不僅是⽅便管理,更是⽅便他⼈能重現我們的成果。相較之下,純 GUI的⼯具就顯得⼗分不便,這也是為何 Excel不會是⼀個做研究或專案的 (主要)⼯具。再來,在眾多可以寫程式的統計軟體中,Stata的指令相對簡單易學。Stata多數的指令都相當直觀,就像是把步驟⽤精簡的⽂字記錄下⽽已。這樣的優點在⼀些比較複雜的資料操

作上尤其明顯,比如說:群組別操作、合併資料、彙整並⽣成變數等。[圖 1-1]提供 R、Stata執⾏的程式碼比較,各位可以猜猜看這是在執⾏哪些功能。

當然,Stata也並非沒有侷限。如果需要⼿刻最新的計量⽅法時,也許 R會是個比較好的選擇。1 此外,Stata的語法也不像程式語⾔那麼有彈性。這可能是因為程式語⾔有許多好⽤的資料結構或物件可以操作。其他統計軟體也有各⾃的長處,像 SAS就廣為業界所使⽤,也和資料庫語⾔ SQL有良好的相性,不喜歡寫程式的⼈也可以參考 SAS的GUI版本 (SAS EG)。SPSS...。最後,R(或是 python)都是免費開源的語⾔,除了⽤途廣泛功能強⼤外,也都有相當龐⼤的社群在維護與開發。

1事實上 Stata也可以像其他程式⼀樣寫函式,但有需求的⼈通常都直接⽤ R了

3

Page 4: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig1-2 Interface

1.2 Interface and Files

[圖 1-2] 為 Stata 的主要介⾯。Result Window(1) 主要呈現指令輸出的圖或報表;Com-mand Console(2)可以⽤來鍵入 Stata的指令;Variable Block and Properties Block(3)會顯⽰⽬前 Stata讀取資料的變數欄位、標籤以及⼀些細節。點選不同變數,就可以在右下⾓的 Properties Block 看到更多細節。若點選變數前的⼩箭頭,則可以直接將變數貼⾄Command Console。左列是 Review Block(4),⽤來記錄執⾏過的指令,有 error的指令會呈現紅字。在此點擊指令可以將其貼⾄ Command Console;雙擊之則可以直接再次執⾏。

Tool bar(5)上有各種功能。右側的「Break」可以終⽌現有程序,其旁邊的「More」則可以讓 Result Window(1) 持續呈現回報的結果 (當結果太多時,並不會⼀⼝氣都呈現在 Result Window 上)。倘若不希望持續點擊「More」,可以在 Command Console 輸入 set more off, perm (see CH.2)。Tool bar(5)中間的「data browser」、「data editor」可以直接瀏覽或修改資料。這兩者分別能藉由 br、 edit指令呼叫。 br在之後檢查資料或檢查指令是否正確執⾏時非常有⽤, edit則較少使⽤。正中間的「do-file editor」相當重要,可以說是利⽤ Stata做研究或專案的核⼼。點擊之可以開啟「do-file editor」的介⾯。具體來說,我們可以在 do-file中,鍵入許多指令然後⼀⼝氣執⾏。此外,記錄在 do-file中的指令可以輸出成「.do檔」,這相當於在 Stata執⾏指令的腳本,也就是讓你的同事或他⼈可以重現你分析流程的依據。[圖 1-3]提供了「do-file editor」的介⾯,⾄於⼀些執⾏上的觀念則會在下⼀⼩節說明,

最後提⼀下各種和 Stata相關的檔案格式。除了上述⽤來記錄指令的「.do檔」之外,

4

Page 5: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig1-3 Do-File Editor

Stata有⾃⼰獨特的資料格式,「.dta檔」。此外還有⽤來記錄所有發⽣的⼤⼩事 (包括 error訊息)的「.log檔」。

1.3 Stata and Related Concepts

⽬前為⽌,我們都還沒有任何和 Stata指令相關的介紹。下⾯條列 Stata與其 code的⼀些註記,關於 do-file的部分,各位可以參考 [圖 1-3]來對照看看。

• Stata,和許多軟體或程式不同,⼀次只能在記憶體中讀取⼀份資料

• ⼤⼩寫有別 (和 SAS不同)

• ⼀般⽽⾔,Stata指令為 <prefix:> <command> <arguements> if <logic exp>, <options>,例如 xi: reg y x1 x2 if age > 18, robust,可以拆解為「xi:」、「reg」、「y x1 x2」、「age> 18」、「robust」,分別代指令的幾個元素(嚴謹⼀點的話,「y」、「x1 x2」是不同的arguement,形式也不完全⼀樣)。

•「//」是 comment operator,其後的所有指令都不會被執⾏。這通常⽤來註記或說明當前的指令

•「*」除了是乘法運算⼦外,置於指令最前⽅時也有 comment的功能。

• 前述 comment operator只對單⾏有效,如果要 comment多⾏,可以使⽤「/*」、「*/」來包夾內容

• 在⾏尾使⽤「///」,可以在次⾏接續前後指令,這在輸出圖表這類設定繁多的指令時(code很長)尤其好⽤

• 在 do-file editor中,可以藉由點擊右上⾓的「Run」、「Do」來執⾏指令。前者會「安靜地」執⾏指令,也就是不在 Results Window 呈現任何結果;相較之下後者則會

5

Page 6: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

「吵雜地」呈現所有結果。(有趣地,我們可以在指令前⽅加上 quietly、 noisily來覆寫呈現上的設定) 2

• 在 do-file editor中,可以藉由反⽩特定區域,再按 do/run來執⾏特定的指令

• 最後也是最重要的,如果不認識指令或想了解更多,可以嘗試 help <command>來檢閱指令的說明⽂件

這邊整理⼀下。⾸先,由於 Stata ⼀次只能讀取⼀份資料,我們常會需要暫存檔案,因此檔案的命名、存放的管理就需要多花⼀些巧思。乍看之下這是 Stata的侷限,但習慣的話基本上不是什麼困擾。再來,在管理檔案時,通常會建立⼀個樹狀的路徑結構 (⾒[圖 2-1]),分⾨別類地來存放原始資料 (input/raw data)、中繼資料 (temp)、分析程式碼(code/.do檔)以及結果 (output)等。這麼做能讓檢索、讀取上更明確且更有邏輯。這點同樣也適⽤於其他的統計軟體上。

最後,在 Coding 上也有⼀些放諸四海的好習慣。比如說,易讀性與可擴充性等。易讀的⽬的是要讓你的同事,甚⾄是幾個⽉之後的你,看得懂你在幹什麼。此外,也能

很快地在 do-file 中「找到」想要進⾏的操作。易讀往往反映在良好的排版 (適當空⾏、縮排與運⽤ comment operator)、命名 (self-explained、wildcard(see 2-6))與 comment上。可擴充性則可以是指程式碼是否可以適⽤到許多任務上,或只需要微幅的修改即可。比

如說,藉由適當的 local變數 (see 2-8)、迴圈 (see 2-5),讓⼀⾏的迴歸指令可以適⽤到許多模型與設定上。

1.4 Reference and Resources

這裡收集了⼀些好⽤的參考連結

Wisconsin Madison的 Stata教學 ”https://www.ssc.wisc.edu/sscc/pubs/sfr-intro.htm”

研究⽣ 2.0 ”https://researcher20.com/2009/04/13/stata”

Stata官⽅整理的學習資源 ”https://www.stata.com/links/resources-for-learning-stata”

2有時候 do-file editor中並沒有「Run」,這時可以右鍵點擊 tool bar再點選客製化 (custimize tool bar)

6

Page 7: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

2 BASIC這節開始會介紹 Stata的語法。本筆記中,⼤部分的 code都以⼀般化的形式表⽰,也就是說各位需要⾃⾏把 argument替換成⾃⼰需要的值,或是適當地增減 option與條件 (⾒1-3列舉的 Stata語法結構)。先前有提到可以⽤.do檔紀錄 Stata的指令,因此我很推薦各位把消化過的指令記錄在.do檔之中。此外也強烈建議讀者們好好保管⾃⼰的.do檔,這除了是各位的⼼⾎之外,也會是之後參考 (抄)code的依據。

在開始各⼩節開始前,很重要地,Stata讀取資料的變數 (或是欄位)⼤致上可以區分成「數值 (numeric)」、「字串 (string)」兩⼤類型,其中的字串在 data browser中以紅字表⽰。不同類型有不同的操作⽅式,此外,如同許多程式慣例,Stata⽤「””」來標注字串,如:”123”、”one2three”。最後,數值變數的遺失值在 Stata中以「.」表⽰,3並且在邏輯

運算上代表無限⼤ (see more in 2-4)。各位不妨在各⼩節留意這些資訊。下⾯各⼩節會利⽤ Stata內的資料 (auto.dta)或是⾃⾏輸入的⼈造資料說明之,4但我也推薦各位可以使⽤

比較複雜的資料實際演練。

2.1 Import/Output

如果不能讓 Stata存取檔案的話,那就什麼也做不了了。雖說先前⼀直強調在 do-file上紀錄指令的重要性,但是在存取檔案時,個⼈是習慣先透過 GUI在 Result Window上產⽣程式碼,⽽後再貼到 do-file上。

⾸先,我想各位需要先開啟⼀份 do-file。[圖 2-1]是⼀個 do-file常⾒的樣貌,包括讀取資料以及⼀些事前準備,下⾯先就事前準備的部分逐⼀說明之。

• clear all,將現有的資料與儲存的變數全部清除。

• capture log close,關閉現有的 log 檔,其中的 Prefix capture可以強制忽略 errormessage,在此可以避免因為 log檔不存在所產⽣的問題。

• set more off,讓 Result Window 可以持續印出結果。注意,這只對同⼀次的執⾏(run/do)有效,如果希望可以在後續的執⾏都維持此設定,可以補上 option , perm。set還可以進⾏更多設定,像是指派 Stata多少記憶體、設定矩陣⼤⼩等。

• cd <path>,即 current directory,可以⽤來設定⼯作路徑,各位可以藉由 pwd (presentworking directory)來做確認。設定好⼯作路徑後,存取任何檔案就可以依照⼯作路徑的相對路徑讀取。[圖 2-1]將⼯作路徑設在”/Stata_proj”,如果我們想讀取”input/auto.dta”(⾒ [圖 2-1]的路徑樹),讀取路徑就會是”input/auto.dta”。5

• log using <path>, replace,可以開啟 log檔並指定儲存位置,option , replace則可以覆寫現有的檔案。

3事實上,Stata有所謂的 extened missing,但 (⾄少對我)並不常⽤,也有許多替代⽅案,see more in ”https://www.Stata.com/manuals13/u12.pdf”

4auto.dta應該會在安裝 Stata時⼀併附上,或是可以嘗試 sysuse auto.dta, clear5順帶⼀提,路徑中的”..”可以返回上⼀層,⽽”~”可以返回根⽬錄。

7

Page 8: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig2-1 General do-file and I/O

關於讀取資料,如果是 Stata的.dta檔的話,可以點選左上⾓的「file -> open」,⼜或是執⾏ use <path>, clear,option , clear可以在讀取的同時先清除當前的檔案 (記得 Stata⼀次只能讀⼀份資料?)。Stata也⽀援許多不同的資料檔案類型 (.csv、.txt等),如果要讀取.dta檔以外的類型,可以點選右上⾓的「file -> import」,從中挑選適合的檔案類型並按指⽰完成讀取。

除上述的讀取⽅式之外,Stata也可以直接在 do-file輸入資料 (⾒ [圖 2-2]),儘管這種⽅式實務上不常使⽤,但在需要⾃⾏創造⼀些簡單資料的場合 (如教學)尤其⽅便。如先前提到的,字串變數 (值)需要透過「””」來標注。此外,input那⾏需要輸入變數名稱,⽽變數類型是被預設為數值 (其中的 float),因此若要輸入字串的話,需要在變數名稱前加上「str<length>」。其中的 <length>是指字串的最⼤長度。請注意,中⽂字串的長度不等於⽂字數,這部分請去查閱「中⽂編碼 (encoding)」。

若要將資料存成.dta檔,可以非常直觀地點擊 Tool Bar左側的「Save」,⼜或是輸入 save <path>, replace。要存成其他檔案類型則可以點選「file -> export」。最後做個簡單的總結 (1)利⽤ GUI輔助讀取資料,再將指令紀錄於 do-file (2)讀資料時加上 , clear,⽽存資料時加上 , replace。

2.2 Data Description

做任何形式的分析前,經常需要先進⾏探索式分析。在不充分了解資料的情形下進⾏

分析幾乎無異於瞎⼦摸象。下⾯介紹幾個有幫助的指令, describe、 codebook、 sum、tab等。

• describe,會概略地描述資料與變數 (事實上我們也可以在右下⾓的 PropertiesBlock找到更多資訊)。

8

Page 9: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig2-2 Input Via do-file

• codebook,可以查看變數的細節 (依變數類型⽽有異),如:變數類型、Range、Unique Value、Missing等。

• sum,可以對「數值」變數進⾏常⾒的敘述統計,加上 option , detail則會進⼀步輸出如百分位、偏峰度等統計量。

上述的幾個指令都可以只使⽤在幾個選定的變數上,例如 sum price mpg, detail。如果去查閱 help file(使⽤ help <command> ),會發現有許多指令後⾯都可以選擇性地加上arguement <varlist>,也就是變數清單,如同上列的「price mpg」。 describe、 sum的輸出結果如 [圖 2-3]所⽰,各位不妨觀察⼀下有哪些資訊。

除了 sum所提供的敘述統計量之外,我們有時也關⼼變數值的次數分佈,尤其是對於類別變數。 tab <var>, m,可以顯⽰變數 <var> 的次數、比例、累積比例,option, m則會⼀併統計遺失值 (missing) 的次數。這個 option 並非預設,但個⼈是習慣⼀定要加上,畢竟很多時候 missing 是值得留意的訊息。若我們想對兩個變數做 (聯合) 次數分佈時 (比如說:gender、race),可以使⽤ tab <var1> <var2>, m。如果想進⼀步去看聯合比例、條件比例的話,可以加入 cell、 row、 col這些 option。這些指令除了有助於了解資料外,有時候也可以⽤來確認⽣成變數的流程是否正確。比如說:我們

會 tab <new_var>, m來確認新變數的次數分佈是否合理、是否有不想要的遺失值,或是藉由 br <varlist>來看看新變數是否確實依想要的⽅式被⽣成。

上述是⼀些最常⽤的指令,以下再條列⼀些也很實⽤的指令

• br <varlist>,在 data browser 中瀏覽 <varlist> 所挑選的變數。忽略 arguement<varlist> 時則是會瀏覽全部的變數,這相當於直接點選 Tool Bar 上的「databrowser」。建議讀者在取得新資料時都先 br⼀下,對該資料有⼀些基本的概念。

• tabstat <varlist1>, by(<varlist2>) s(<statistic>),依照不同 varlist2(通常是類別變數)

9

Page 10: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig2-3 Describe and Sum

的值回報 varlist1的統計量 (statistic)。這個指令可以視為 tab、 sum的活⽤,⼀些細節 (如統計量的名稱)在 help file都有詳細的紀錄。

• corr <varlist>,相關係數矩陣。option , c則可以回報共變異數矩陣。

若要認識資料,繪製圖表也是很好的⽅法 (如 scatter、histogram),我會在 2-9提到⼀些最基本的繪圖。6 最後強調⼀下,我無法在此把每個功能都交代清楚 (更何況有些我從來沒⽤過)。想深入了解或查詢特定功能的話,還是請多參考 help file。

2.3 Arithmetic Manipulation

這⼀⼩節會談到如何操作、⽣成⼀些變數。⼤部分 Stata ⽣成變數時都是對 variable(s)/columns 做 item-wise 的操作。我們可以使⽤ gen <var> = <expression>來⽣成變數,以及將 gen替換為 replace來修改現有的變數。以下是⼀些說明與簡單的範例。

• 所謂 item-wise的操作是指 (就向量或某種清單來說),將同樣位置的元素進⾏操作(如:加減乘除)。在資料上,也就是操作同⼀個樣本點上不同變數的值。

• <expression>是由變數和運算⼦組成,如: var1^ 2 + var2*var3)/100

• gen total_score = micro + macro + stat,將每個樣本點的 micro、macro、stat 值加總,「⽣成」⼀個新變數。

6想要多瞭解 Stata繪圖的話,可以參考”https://www.ssc.wisc.edu/sscc/pubs/4-24.htm”。

10

Page 11: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig2-4 Normalize by egen

• replace GDP = C + I + G + EX - IM,加總消費、投資、政府⽀出、淨出⼝,「取代」掉現有的變數 GDP。

除了常⾒的加減乘除與 power運算⼦外,Stata也提供許多內建的函式,如 log()、exp()、sqrt()等。7

然⽽有時候我們想⽣成的變數涉及到某個變數的匯總 (如 mean、std、標準化)8,或者我們需要對好幾個變數做 item-wise的彙整。這時候, egen <var> = <func>提供了相當多樣的功能,下⾯以幾個常⾒的 function說明之

• egen mean_stat = mean(grade_stat),⽣成⼀個變數來記錄統計成績的平均。

• egen max_grade = rowmax(grade_micro grade_macro grade_stat),⽣成⼀個變數來記錄每個⼈最⾼分的成績 (item-wise)。

• egen <var> = total(<logic exp>),計算有多少樣本符合條件(<logic exp>會在下⼩節說明)

先前提到的標準化的指令如 [圖 2-4]。我在此是使⽤ egen來處理,也就是先⽣成變數來儲存 mean、std,再透過 gen進⾏ item-wise的操作。9 最後,下⾯再補充⼀些和⽣成變

數相關的實⽤指令。

• gen <var> = _n,依照樣本排序給予從 1開始的 index

• gen <var> = _N,回傳總樣本數

• destring <var1>, gen(<var2>),將「字串」變數 var1變成「數值」變數 var2。請注意,只有「看起來像數值」的字串變數可以進⾏轉換。此外, tostring則可以進⾏反向操作。

• encode <var1>, gen(<var2>),將字串變數轉成「類別化」的數值變數

例 1、2 的 _n、_N 是兩個有趣的表⽰法,分別反應樣本點 index 與樣本數。10 關於例

3、4,由於字串與數值變數只能各⾃進⾏特定的操作,我們很常需要先做轉換。例 37see more ”https://www.Stata.com/manuals/fnmathematicalfunctions.pdf”8和 item-wise的操作不同,涉及到了跨樣本點的操作9之後的章節,我則是會執⾏ sum 並從這個指令的「return list」來索取「彙整的值」10_n也可以被活⽤來⽣成等差、等比數列,⼀些更⼀般化的數列則可以參考 egen 底下的 seq()、fill()函數

11

Page 12: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig2-5 Logic Operaters

的 destring、 tostring可以⽤來切換變數類型。例 4中的 encode會將變數類別化 (在 databrowser中呈藍字,see 2-6)。

2.4 Logics and Applications

我們經常會依照不同的條件⽽有不同的操作。最常⾒的條件是由 if開頭,再加上由變數/數值、運算⼦與邏輯運算⼦ (⾒ [圖 2-5])組成的 logic expression。Stata的邏輯運算⼦和許多程式的慣例⼀樣,此外許多條件也可以利⽤「且 (&)」、「或 (|)」組合在⼀起。多了條件式後,就能進⾏更多特定的操作。下⾯搭配先前提過的幾個指令舉實例說明。

• tab cred if female == 1 & dep == ”Econ”,對經濟系女⽣做學分數的次數分佈

• replace grade = ”C-” if score > 50 & score <= 60 & makeup==1,將滿⾜條件的⼈的grade改為”C-”

• gen old = 1 if age >= 80 & age < .,對於 80歲以上且年齡非遺失的⼈,⽣成⼀個變數來標註年老

這裡有幾點要注意。⾸先,請留意指定值 (= assign)和等值 (== equivalence)間的差異;其次,指定字串變數值時,需要加上「””」(如 [圖 2-2]中的輸入字串值);最後,如在本節開始前提到的,數值資料的遺失值「.」,在 Stata中是被視為無限⼤。各位可以想想看如果少掉 age < .會發⽣什麼事。

除此之外,條件式本⾝也有許多應⽤,如篩選資料或檢查樣本點是否符合條件,以

下介紹⼀些指令與條件式的搭配。

• drop if <logic exp>,丟掉符合特定條件的樣本點

• gen <var> = (<logic exp>),⽣成符合條件的 indicator(符合為 1,不符合為 0)

12

Page 13: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig2-6 Loop

• assert <logic exp>,檢查條件是否成立

drop除了丟掉特定樣本點外,也可以藉由 drop <varlist>刪去特定變數。此外,指令 keep的⽤法和 drop⼀樣,只差在功能完全相反 (看名字應該就能理解)。例 2在⽣成indicator時非常⽅便 (當然,我們也可以分別寫 gen、 replace ),然⽽這樣的⽤法需要特別注意。具體來說,他會⽣成「A 與非 A」,但「非 A」有時候不⼀定是我們想要的,例如當 A代表 18歲以下時,「非 A」就會是「18歲以上以及 missing」。最後,例 3在清理與檢查資料的過程非常實⽤。比如說,我們可以檢查是否體重有負值與遺失值,

assert weight >= 0 & weight < .。

2.5 Loop

迴圈 (Loops)可能是程式中最具代表性的基本⼯具之⼀,好的迴圈不僅簡潔易讀,也可以很⽅便地進⾏修改。Stata的迴圈主要有對數值的 forv,以及對 item的 foreach。兩者的結構基本上⼀樣,[圖 2-6]各舉了⼀些簡單的範例與輸出結果。簡單來說,迴圈就是在指定的範圍內 (1/5,1 2 3 4 5),依序將值帶入迴圈變數 (iterating variable)中 (i),然後進⾏指令,如圖中的 display (印出值的簡單指令)。注意,迴圈內的指令是使⽤「{ }」包起來,⽽迴圈內的迴圈變數需要利⽤「`」、「’」包起來 (` i’)。相較於 forv, foreach很多時候是⽤來對⼀個 list進⾏迴圈,例如 [圖 2-6]對⼀堆變數 (price length weight)的標準化。我們其實也可以在迴圈內再包迴圈 (nested loop),但請把每⼀層的迴圈變數與 loop over的對象給註記清楚。

好的迴圈可以讓 coding更簡潔,但若缺乏適當的排版、命名與 comment的話,反⽽容易造成許多困惑。11 最後補充⼀下,Stata也可以寫其他程式常⾒的 while迴圈以及

11⼀些迴圈 coding上的習慣:(1)迴圈內的指令縮排;(2)有意義的變數命名 (self-explained,如 [圖 2-6]中的

13

Page 14: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

if-else條件式,但多數時候 forv、foreach就很夠⽤了。

2.6 Label and Naming

這⼩節會談到變數標籤、類別變數以及變數的命名。這些東⻄也許不會直接和清理與分

析資料有關,但可以讓閱讀資料時更明確易懂。標籤的概念是這樣的:⾸先,每個變數

都可以有標籤,這可以在 Variable Block中查看。除此之外,我們也可以給變數的「值」標籤,⼜或是說定義⼀個值對應到標籤的 mapping。有趣的是,這樣的 mapping也有⼀個名稱 (下稱值標籤 map)。將這個 mapping套⽤到變數⾝上就可以完成類別化 (在 databrowser中呈藍字)。類別化後的變數在 data browser以及許多指令的輸出結果中,將以值標籤呈現,但其本質上 (運算上)仍然是數值。下⾯做⼀些簡單的整理

• label var <var1> <string>,將 var1標籤上 string

• label define <map name> <value 1> <label 1> <value 2> <label 2> ...,定義值標籤map。其中的 <map name>,是這個 mapping的名稱。

• label value <varlist> <map name>,將定義的值標籤 map套⽤在 <varlist>上

• label dir,查看值標籤 map

• label list <map name>,列出值與標籤的 mapping。<map name> 其實也可以是<map list>,即列出 <map list>中所有 mapping的值與標籤,這些差異還是老話⼀句:請參考 help-file。

• label drop <map name>,丟掉定義的 mapping

請注意,值標籤的值只適⽤於「整數」與「某些遺失值」,因此若想適⽤於字串變數時,

可以直接利⽤先前提到的 encode完成類別化。對於某些數值變數,尤其是連續變數,我們需要先將其轉變為整數 (integer)的數值變數,再進⾏類別化。12 此外,各位也不妨確

認⼀下,如果 mapping沒有在變數⾝上完整定義的話,會怎麼被處理。

[圖 2-7]利⽤⼀個⼈造資料來間單地展⽰⼀些 label的實例與結果。幾個可以注意的地⽅:(1)female的 missing在 label時是怎麼被處理的 (2)由 label list可以得知,我們產⽣了兩個值標籤 map(dep2/gender)(3)右下⾓的 tabstat,是以值標籤 (male/female)顯⽰分組 (4) encode是如何建立值標籤 map的呢 13

除了標籤,變數命名也是⼀件值得花⼼思的事。好的命名邏輯可以省下許多查詢甚

⾄ coding的時間,尤其是我們可以利⽤「wildcard」來⼀⼝氣呼叫⼀堆變數 (varlist)。⼀些修改變數名以及利⽤ wildcard的⽅法列舉如下。

• rename <var1> <var2>,可以將 var1改名為 var2

var代表的是 loop over變數);(3)下⼤括號 (})要獨⾃⼀⾏12我們有 gen 、 replace 以及條件式,所以這件事其實不難。如果各位感到⿇煩,可以進⼀步參考 recode 以

及 egen 底下的函⽰ cut()13 encode 的值標籤就是原本的「字串值」,且值標籤 map的名稱就是「變數名稱」。

14

Page 15: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig2-7 Labeling

• rename (<varlist1>) (<varlist2>),⼀⼝氣更改許多變數的名稱 (varlist1 -> varlist2)。

• <var>*,可以呼叫所有以 var開頭的變數。

• <var>1-<var>10,可以呼叫 var1到 var10

例 3、4的wildcard有很多⽅便的運⽤,像是 sum <var>*、 egen <var1> = rowmean(<var2>*)。因此,命名時不妨考慮幾點:(1)名稱能清楚反應變數內涵 (self-explained);(2)概念類似的變數可以加上同樣的 prefix或 suffix,以⽅便利⽤ wildcard;(3)名稱如果是「短句(詞)」的話,可以⽤⼤寫或「_」來分隔單字,如 AvgScore、Mean_GPA。

2.7 By Command

如果有別的程式經驗的話,群組別的操作常常需要花上不少⼒氣,但在 Stata中,只要利⽤ prefix by:就可以輕鬆完成這項任務。 by <varlist>: <command>可以幫助我們完成群組別的操作,也就是依 <varlist>的值分組別執⾏ <command>。請注意:(1)並非所有指令都能搭配 by使⽤ (2)在使⽤ by前,需要先將變數進⾏ sorting。Sorting的指令很簡單,以下條列說明之

• sort <varlist>可以讓樣本樣本點依照 <varlist>進⾏升冪 (numeric)或字⺟別 (alpha-betical)的排序。

• gsort (+/-)<var> (+/-)<var> ..., gen(<var>) mfirst是⼀個更⼀般化的 sorting,透過在變數前⽅加上正負號可以設定排序⽅向。

• option gen(<var>)可以⽣成⼀個排序順序的 index(有序,但距離無意義)

• option mfirst則可以設定是否將 missing排在最前⽅

最後,在 sorting之前,請留意 sorting的過程是否 stable(help file內有個清楚的例⼦),以及後續的指令是否會因此⽽受影響。

15

Page 16: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig2-8 By Commands

回到 by command,事實上,by可以直接和 sorting結合成 bys。[圖 2-8]展⽰了⼀些 by command的運⽤,其左上、右上分別是組別操作前後的資料,以下條列說明之

• bys <varlist1>: <command>,先 sort on <varlist1>,然後對 <varlist1>進⾏群組操作。

• bys <varlist1> (<varlist2>): <command>,先 sort on <varlist1> <varlist2>,但是只對 <varlist1>進⾏群組操作。

• 關於 [圖 2-8]的幾個例⼦...

– 例 1在算組平均,這⼀類 by、 egen的搭配非常常⾒。

– 例 2在算組樣本數,2-3提到的「_N」在這裡就相當實⽤。當然,我們也可以⽤「_n」來產⽣組內的 index,只要資料的排序是符合預期的。

– 例 3試圖找出組內的第⼀筆成績值。請注意,我利⽤ bys ID (try)來確保組內排序正確後,再利⽤ grade[1]取出第⼀筆成績值。各位不妨猜猜看 grade[_N]會跑出什麼呢?

– 例 4試圖計算每⼀次嘗試 (try)前後的成績差異。記得「_n」可以回傳當前的index嗎?當例 4的指令套⽤在每個樣本點時,就會是當前的成績值減去「組內前⼀個樣本點」的成績值,也就是說,當在某組第 2個樣本點時,就會計算grade[2]-grade[1],⽽這也是為什麼在各組第 1個樣本點時會產⽣ missing。14

– 例 5想要取出「第幾次」的成績最好 (沒有呈現結果)。雖然這無法⼀次到位,但善⽤現有指令的話並不困難。

善⽤ by command 可以幫忙省下許多功夫,但有時候 code 好懂比起省空間更重要。如果各位不喜歡 by 和 sorting ⼀起做的話 (像是覺得第 2 點的寫法令⼈困惑),改

14各位也可以想像我們在分組跑迴圈。

16

Page 17: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

成 sort與 by兩⾏來寫絕對不會有問題。By command 還有很多實⽤的運⽤,像是搭配 egen底下的 total(<logic exp>)來計算組內符合條件的個數。最後,by command有時候產⽣的結果並不直觀,尤其是與條件式⼀起使⽤時,這時可以利⽤ tab、 assert之類的指令檢查,抑或是瀏覽 data-browser。

⽬前為⽌,我把 Stata最基本的操作都帶過了。從存取資料 (2-1)、探索與⽣成變數(2-2, 2-3),接著進⼀步利⽤條件式與迴圈完成或簡化特定的操作 (2-4, 2-5)。我們也學會把利⽤標籤以及 wildcard來輔助閱讀與操作 (2-6),最後我們學會群組別的操作 (2-7)。希望⽬前為⽌,我能夠說服各位 Stata真的很好學,⽽且也是個實⽤的⼯具。15

2.8 Local Variable and Return List

我們常常在 Stata中執⾏數個指令已完成某個步驟或程序,在其中我們經常性地會提到某個數值 (例如年齡在 n 歲以下) 或是某個變數 (想使⽤的依變數)。當想要更動這些值時,逐⾏檢查並取代可能不是明智之舉,畢竟這很⿇煩⼜可能會出錯。比較好的⽅法將

這些經常被提到的值參數化,也就是設成 Stata中的 local變數來表⽰,這樣往後只要更動 local變數所指涉的值即可。以下條列說明之...

• local <loc_var> <obj>可以將 <obj> 指定給 local 變數 <loc_var>。在之後的指令,可以透過「` <loc_var>’」呼叫 local變數。

• Local變數可以是數值、某變數、字串或者是變數清單 (varlist)。

• Local變數的呼叫僅對當次的 run/do有效。如果想要⼀個在關閉 Stata前都有效的變數,可以使⽤ global變數:將指令中的 local改為 global即可。Global變數可以使⽤「$<global_var>」呼叫之。

[補個例⼦]

Stata 的各項指令事實上很像程式語⾔的函數:執⾏之後會對資料進⾏某種操作、印出某些結果以及回傳 (return)某些訊息。在操作某些指令之後,可以透過 return list來查查看該指令是否有留下⼀些實⽤的資訊給我們。像是我們執⾏ sum <var1>之後,可以透過 r(mean) 來取得 <var1> 的平均值。在之後的第四節,還有個針對估計型指令的 ereturn list,這對於取得⼀些常⾒的統計量 (SSE, R2...)非常⽅便。

2.9 Plotting, String Function and Miscellanea

Stata的繪圖與字串函數有許多功能,也因此值得⼀個章節好好介紹。但其中許多基本的功能就已經相當實⽤了,因此這⼩節會先「簡略地」做些說明。最後,我會補充⼀些先前

沒提到,但也很實⽤的指令。

各位想必在統計課,甚⾄是國⾼中的數學課就接觸到許多將資料以圖表表達的⽅法 (比較潮的說法是資料視覺化)。點擊 Stata左上⽅的「graphics」就可以發現許多繪圖⼯具。我

15如果各位⼀頭霧⽔的話,有可能是我的舉例與說明不夠好,但也推薦各位多⽤資料試著做中學,以及多參

考 help file以及利⽤ google。

17

Page 18: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig2-9 Some Stata plots

個⼈很建議繪圖時善⽤ Stata的 GUI,也就是靠點擊圖形化介⾯來完成複雜的圖表設定,然再將 Result Window上的 code複製到 do file上。然⽽,對於簡單的圖表,也不妨稍微留意⼀下相關的指令。[圖 2-9]利⽤ auto.dta,來展⽰⼀些結果,雖然不⼀定有什麼具體意義就是了 (笑)

• scatter <varY> <varX>,以 varY為 y軸、varX為 x軸繪製 scatter plot。

• line <varY> <varX>, sort,以 varY為 y軸、varX為 x軸繪製 line plot,option , sort會以 varX的排序繪製 line plot。

• Option title(<str>)、 xtitle(<str>)、 ytitle(<str>)分別可以指定圖表的上標題、x 軸名稱、y軸名稱。

• Option xline(<value>),可以在 x軸變數為 <value>的地⽅標上參考線。

• Option by(<var>),依 <var>的值來繪製 subplot。

• graph bar (<stat>) <varY>, over(varX),依 <varX> 的值分組繪製 <varY> 統計量<stat>的長條圖。這其實就是 2-2提到的 tabstat的圖形化版本。

• hist <var>可以對 <var>的次數分佈繪製直⽅圖,option bin、 width可以⽤來調整柱寬,option normal則會附上常態分佈的機率密度 (依 <var>的 mean, std)。

18

Page 19: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Stata的繪圖功能還有許多細節可以設定,以下條列⼀些功能,有興趣的⼈可以善⽤網路資源查詢之

• 更改 (如 scatter)圖中的標記 (marker)、x軸與 y軸的刻度與顯⽰⽅式 (ticks)等

• 分群繪製在同⼀張圖上 (⽽非以 subplots的⽅式分開呈現),並且以客製化的 legend來標⽰群組

• 將不同的繪圖⽅式呈現在同⼀張圖上,如 scatter與 linear fitted line

• 將多張圖合併在⼀張⼤圖底下

• 在圖的左右側分別呈現不同的刻度。

字串變數其實相當常⾒,舉凡國家名稱、住址、⾝分證字號等都是。但字串變數很明顯

地無法進⾏常⾒的數學運算,因此我們常常會需要先從這些字串中取出訊息,然後將這

些訊息以數值變數 (類別)表⽰,比如說:從住址中取出縣市、從⾝分證字號中取出第⼆碼 (反映性別)。以下條列⼀些字串處理上的概念以及其函式

• 字串變數的 missing 是「””」,然⽽在 data browser 中,⾁眼所⾒的空⽩並不⼀定是 missing,也不⼀定反映同樣值。我們所⾒的空⽩可能是「⼀堆 whitespace」或是「tab」或是兩者的組合。

• 函式 trim()可以去除字串前後的空⽩,例如將” Cool ”變成”Cool”

• substr(<str>,n1,n2)可以從字串 <str>中截取第 <n1>個字⺟開始,長度為 <n2>的片段。

• 倘若我們要擷取⾝分證中的第⼆碼,可以利⽤ substr(”A123456789”,2,1)

• strpos(<s1>,<s2>)會回傳字串<s2>在<s1>中⾸次出現的位置,例如 strpos(”Stata”,t)就會是 2。若 <s2>不存在於 <s1>之中就會回傳 0,因此這也可以⽤來檢查特定字串是否存在於某字串之中。

• 請注意,如果我們處理的是中⽂字,那麼「長度」、「第幾個」的概念就不能直接適⽤,但通常可以查到 unicode版本的函式使⽤,例如 usubstr()、 ustrpos()。16

• split <strvar>, gen(<prefix>) parse(<str>),將字串變數 <strvar>依 <str>切成片段,並儲存成數個以 <prefix>開頭變數。例如變數 (⽇期)的某個值「”2010-01-02”」,以「”-”」切成片段就會被存成三個值分別為「”2010”」、「”01”」、「”02”」的變數。17

• 這些字串函數基本上都可以套⽤在字串變數⾝上,只要將其中的字串 argue-ment<str>換成字串變數 <strvar>即可。結果就會是對字串變數的每個樣本點上的值做操作 (item-wise)。

16!!NEED DETAIL17當然,此例也許⽤時間相關的函數處理更⽅便。請參考 date() 、 month() 等時間函式。

19

Page 20: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

為了從⽂字中取得資訊,當然就有需多對應的字串函數可以使⽤,甚⾄也可以利⽤正規

表達式 (regular expression)。沒有⼈隨時都記得這些指令,但熟悉⼀些常⾒的功能有助於快速在 google(或 Stata help file)上找到對應的指令。18

最後,由於本⼈的怠惰,以及不知道該如何歸類部分指令,因此我把⼀些也很實⽤的指

令與相關說明收集於此

• order <varlist>,依照<varlist>的順序從頭排序變數,option , after(<var>)、 , before(<var>)可以選擇從何開始排序。

• recode <varlist> (rule1) (rule2) ...,依照 rules重新指派變數值。

• 查看 help file可以發現所謂的 rule可以有很多形式,像是 (0/60 = 0)就是將 0到 60的值重新指派為 0。

• recode可以省下寫很多⾏ replace的空間。但要要注意幾點,(1) 請⼀⼝氣完成recode,否則可能會有新的 rule 把剛更新的值⼜取代掉的情形;(2) 請⼩⼼在某些rule之下,原邊界值到底會被分到哪⼀個新值。19

• list <varlist> in 1/10,在 Result Window上列出樣本點 1-10的 <varlist>。

• list有時候會比 br <varlist> if <logic exp>更⽅便,其後的條件 in 1/10,是指前 10個樣本點。

18Stata的字串函數 https://www.Stata.com/manuals/fnstringfunctions.pdf19對於連續變數,我們可能會擔⼼ (2),這個問題可以參考看看 egen <var> = cut() 。

20

Page 21: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig3-1 Append

3 DATAWRANGLING根據 wiki的定義,Data Wrangling是指將 raw data轉換成適合後續分析的形式,這可能涉及到將非結構化資料結構化、清理資料、合併資料等。20 也許有些⼈會認為這些步驟

相較於分析,不過是苦⼒與勞⼒密集的⼯作罷了。但我認為這個步驟比起分析更無跡可

尋 (學),也不容易建立⼀個明確的⼯作流程。準確來說,這是⼀個相當吃經驗的步驟。Data Wrangling不僅需要了解 raw data以及分析需求,也需要有⼀個易懂、容易調整與反饋的⼯作流程。尤其對於處理巨量資料(雖然本⼈沒有相關經驗),不恰當的步驟可能

就會需要花上相當⾼的時間成本。

3.1 Combining Dataset, Append and Merge

這⼀⼩節會介紹如何合併不同資料。合併資料基本上可以分成垂直合併與⽔平合併,分

別可以使⽤ Stata的 append、 merge來完成。

[圖 3-1]利⽤兩年成績的⼈造資料簡單地展⽰⼀下 append,下⾯條列⼀些說明

• append using <path>,將現有資料與 <path>上的檔案垂直合併

• 兩筆 data要進⾏⽔平合併時,需要確認 (1)變數名稱是否⼀致 (2)變數類型是否⼀致。本例中顯然兩條件都不符合,也因此我們透過 rename、 tostring改名與轉換變數類型。

• 在合併資料前,我先在各資料中創造了變數 year來標注資料的年份,各位可以想想看不標年份就垂直合併可能造成的混淆。

• 合併後的資料經過 order、 sort整理,最後藉由 isid確認 id-year是否可以「identify」這個垂直合併後的資料。

20現在的資料可能有非常多種形式,如影像、⽂字、聲⾳等,將這些資料轉換為像 excel 中的表格 (或稱dataframe)就是資料結構化;此外,清理資料顧名思義就是掃除資料中骯髒、妨礙分析的部分,包括異常值、遺失值等。

21

Page 22: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig3-2 Merge

最後提到的「identify」資料是個重要的概念,也就是⼀組變數 (的值)是否在資料中是唯⼀的,這組變數⼜稱「identifier」,例如 [圖 3-1]中 year1以及 year2的 id。21當然,作為

identifier的變數也要有意義:說明樣本點的⾝份、可以連結⾄其他資料等。處理不同資料時,我們需要時時銘記哪⼀組變數是 identifier,這點在各種資料的操作上都很重要。

[圖 3-2]接續先前垂直合併後的成績資料,接著要嘗試將其利⽤變數 id和個⼈背景資料⽔平合併。下⾯條列⼀些說明

• merge <type> <varlist> using <path>,將現有記憶體中的資料 (⼜稱 master) 和<path> 上的資料 (⼜稱 using) 合併。master 與 using 中具有相同 <varlist> 值的樣本點 (本例中的 id)會被⽔平合併。當然,我們需要好好確認 <varlist>的名稱和變數類型是否在 master與 using中⼀致。

• <type> 是⽤來說明 <varlist> 的值在 master 與 using 中是否唯⼀ (identified,若非唯⼀則標⽰ m),因此 master 與 using 依序標⽰ (是否為⼀) 可以分成四個種類,1:1、1:m、m:1、m:m。本例中的 id在 using是唯⼀的,但在 master中並不是,因此 <type>標⽰為 m:1。

• ⼀旦樣本點沒有出現在 master 或 using 之中,就無法藉由 <varlist> 進⾏對應的⽔平合併 (本例的 master 中缺乏 id=6,using 中缺乏 id=5),因此這些樣本點就會在master或 using的變數上呈現 missing。⽔平合併後⽣成的類別變數 _merge正是⽤來記錄這些情形 (master only、using only、matched)。

• ⽔平合併後,我把⼆元變數 (binary/dummy)GSAT、ASR、Others重新彙整成⼀個類別變數,算是⼀個 gen、 label value的應⽤。

第 3點可以再進⼀步說明:Stata在⽔平合併時是預設包括那些僅出現在 using或 master21也就是 SQL中”key”的概念。...foreign and local key...

22

Page 23: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig3-3 Merge/Join Type

的樣本點,如 [圖 3-3]范式圖右下⾓所呈現的 OUTER JOIN。22 如果需要別種合併⽅法,

我們其實可以很⽅便地利⽤變數 _merge丟去不想要的樣本點即可。然⽽,再丟去樣本點之前,最好要先想想看樣本點在 master或 using中遺失的原因,以及這樣的遺失是否會影響後續的分析與推論。最後,option keepusing(<varlist>)可以⽤來選擇需要合併哪些using中的變數,當我們 merge的 <varlist>和 keepusing的 <varlist>⼀致時,事實上我們就只是在檢查樣本點在 master與 using出現的情形。

3.2 Aggregate and Reshape

前⼀⼩節有提到「identifier」的概念:某⼀組變數是「identifier」是指其值在資料中是唯⼀的,像是 [圖 3-2]中的 id-year。這樣的⼀組變數 (或是這個資料本⾝)可以想成是⼀個層狀的結構,像是我們會說:⼩明 (id)⼤⼆ (year)的 gpa如何等等。假設這些變數有某種排序,如「id -> year」,排序中的每個變數都是⼀個「層級」,⽽前⽅的變數是較⾼的層級。其他變數也有層級的概念,像是個⼈背景就是在「id」這⼀層:其值對於 id以下的層級是固定的。⾄於成績就是「id-year」的層級 (或是,如果層級的排序明確的話,也可以說是「year」這個低層級)。23 這⼀⼩節我們會談到⼀些和層級有關的指令:彙整

變數⾄較⾼層級、將低層級資料重新以⾼層級表⽰ (或反之)。這些分別可以利⽤ Stata的 collapse、 reshape實現。

[圖 3-4]利⽤⼈造的成績資料說明如何彙整變數⾄⾼層級,這邊我們假設 id是較⾼層級,也是我們想彙整到的⽬標層級。下⾯條列說明之

• collapse (<stat>) <new_var1> = <var1> <new_var2> = <var2> ..., by(<var_i>),將變數 <var1>、<var2>等依統計量 <stat>彙整⾄ <var_i>的層級上 (或說,以 <var_i>

22這些多樣的合併⽅式參考⾃ SQL的 JOIN。23id-year的順序反過來也說得通,但有些例⼦就會有比較明顯的排序,如:school-class、county-city等

23

Page 24: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig3-4 Collapse/Aggregating

為組別的彙整)。換句話說,這個指令可以同時彙整「許多變數」的「許多統計量」⾄較⾼的層級,如本例中的 name。

• 如果不⽤ <new_var> = <var1>的⽅式指派新舊變數名稱,也可以只在統計量 <stat>後⾯輸入變數名,如本例中的 absence,這樣彙整後的變數還會是原本的名字,但請⼩⼼彙整不同統計量時新變數名稱衝突的情形。

• 這個指令可能會很長,請善⽤「///」以及縮排。24

關於這個指令,各位也不妨想想看幾件事:(1) 是否可以利⽤ bys:、 egen做到⼀樣的事、(2)彙整後的資料似乎遺失了學科的資訊 (尤其是對於最⼤最⼩值),如果我希望彙整後能保有這些資訊該怎麼做呢?25

有時候基於運算或是展⽰等理由,我們希望將低層級的資料改以⼀堆變數欄位表⽰

(to wide form),或是相反地,將⼀堆內涵類似但種類不同的變數,依其種類堆疊成 (新的)低層級 (to long form),也就是所謂的 reshape。26 說穿了,reshape本質上並沒有改變資料內容,不過是像七巧板⼀樣地重新組合⼀些資料中的元素罷了。在開始解說前,不

妨先留意⼀些資料中的元素:(1)⾼層級變數 (2)低層級變數的名稱與值 (3)分析變數的名稱與值。

[圖 3-5]⽤⼀個簡單的例⼦來展⽰ wide form與 long form以及 reshape的指令,我將其中同樣的元素⽤同樣的顏⾊框起來。27 下⾯條列說明之

24縮排的⽬的通常是要表⽰⼀段指令還沒結束,像是迴圈內的指令也常會縮排表⽰。25這兩可都可以利⽤ 2-7的群組別彙整處理 (也許無法⼀次到位),然後在捨去重複或不必要的變數與樣本點26⽂字解釋也許很難理解,但看⼀些實例 ([圖 3-5]或是 help file)通常就可以抓到⼀些概念27如果你認真把 reshape當成七巧版操作,那麼你會發現 wide form少了低層變數名稱,也因此轉換回 long

form時,要在 code中把低層變數名稱還回去。

24

Page 25: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig3-5 Reshape

• reshape wide <prefix_var>, i(<var1>) j(<var2>),將資料轉換為 wide form。其中的<var1>、<var2> 分別是⾼層級 (name) 與低層級變數 (subject),⽽ <prefix_var> 是現有的、想要分析的變數 (grade)。注意,新的變數名稱是「<prefix_var><value ofvar2>」,也就是本例的 gradeMicro、gradeMacro、gradeStat。

• reshape long <prefix>, i(<var1>) j(<new_var>),將資料轉換為 long form。<new_var>是⼀個新⽣成的變數,代表新⽣成的低層級變數名稱。<prefix>則是⽤來標註分析變數 (們)共有的 prefix,這個 prefix也將做為 long form中分析變數的名稱。最後,prefix之後的部分則會作為低層級變數的值。

• 分析變數<prefix_var>/<prefix>也可以是⼀個 varlist,但請留意,在 reshape long時,同⼀組分析變數需要有清楚對應的 prefix。

• 當低層變數類型是字串時,需要加上 option string

• reshape時除了代表不同層級的變數以及分析變數之外,其他變數的處理規則如下:(1)to wide時,⾼層級變數會被很⾃然地帶到 wide form中,但如果低層級變數沒有放到 <prefix_var>中的話,就會產⽣ error;(2)to long時,其他變數必定是⾼層級變數,因此也會很⾃然地被帶到 long form之中。

• Long form 中,有時候⾼層變數底下不⼀定包括所有低層變數的唯⼀值 (uniquevalue)(本例中的 Macro、Micro、Stat)28,若轉換成 wide form,仍會產⽣⼀組對應低層變數唯⼀值的變數,但其中有些值就會是 missing。

28各位可以想像 [圖 3-5]刪去某些樣本點後,有些⼈ (name)就會缺乏某些學科 (subject)的資訊

25

Page 26: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

Fig3-6 Duplicates

觀察 reshape 的指令,可以看到 Stata 巧妙的利⽤變數名稱以及 prefix 作為切換依據。Reshape的⼀些規則看似複雜,但實際操作過後會發現這並不難理解。最後有⼀個⼩建議:reshape前盡可能地簡化資料,丟去沒必要的變數。

3.3 Duplicate and Missing

這⼀⼩節會介紹 duplicates系列的指令以及再訪 missing。很多時候我們明確的知道資料應該是在某⼀個層級,或是某⼀組變數應該作為 identifier。 duplicates可以幫我們偵查這些情形,找出不合理的重複值。⾄於Missing的部分,我在 2-4已經說明了 missing值在邏輯運算中如何被操作,但這邊會再把相關的概念重新整理⼀次,並且舉例 missing在⼀些指令中的影響。當我們清理資料時,很常需要去檢查重複值與遺失值,也因此這些

指令相當實⽤。

下⾯以 [圖 3-6]為例,條列說明 duplicates系列的指令

• duplicates report <varlist>,回報 <varlist>重複的情形。[圖 3-6]左下⾓展⽰了回報的結果:重複次 2次的樣本點共有 2筆,也就是有 1筆是多餘的;重複 3次的樣本點共有 6筆,也就是有 4筆是多餘的 (6− (6/3))。

• duplicates tag <varlist>, gen(<var>),對於 <varlist> 值重複的樣本點,利⽤ <var>標記重複次數,即圖中的 dup。

• duplicates drop,對於重複的樣本點 (所有變數值⼀樣),只留下「第⼀筆」重複的樣本點。

• duplicates drop <varlist>, force,對於 <varlist>值重複的樣本點,只留下「第⼀筆」重複的樣本點。本例中,我們認為 name-subject應該要 identify這組資料,並決定只留下成績最⾼的那筆,因此我們先⽤ gsort排序,讓想留下來的樣本點排在重複

26

Page 27: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

樣本點中的「第⼀筆」。29

最後,關於 missing,以下做⼀些整理

• 數值與字串變數的 missing 分別為「.」、「””」,當然有些時候其他值的意義也是 missing,像是「0」或是「” ”」,30 因此我們需要細⼼地檢查資料,比如

說透過 tab、 sum以及繪圖來觀察變數的唯⼀值或是分佈,並適時將某些值改成missing。

• Missing在數值變數的邏輯運算上被視為無限⼤。有趣的是, egen底下的 max會排除 missing。如果各位覺得這些規則煩瑣 (應該還好),還是⼀個老建議:有疑惑時就查閱 help file。

• If條件⽰可以輕易地幫我們挑出 missing。如果不喜歡⽤⼀長串的 <logic exp>表⽰的話,也可以試試看,如: br if missing(v1, v2, v3...),只要 v1、v2、v3任⼀變數有 missing(無論變數類型)就會被挑出來。

• 最簡單 (可能也是最常)處理 missing的⽅式就是逐列刪除,即完全捨去該樣本點。然⽽,這麼做的風險就是忽略 missing本⾝可能隱含的資訊 (也許,missing並不是隨機的)。有些時候我們可能會補值或是將變數類別化 (包括 missing類別)。31

29右上的圖⽰僅停在 sorting,後續的 duplicates drop就請⾃⾏嘗試30這些可能導因於觀測時的失誤 (比如說測量 PM2.5的儀器測不出接近 0的值)或是資料提供者的處理31補值的⽅法可以是取變數的平均,或是利⽤其他變數建立模型去預測遺失值。有些機器學習的⽅法也可以

應⽤在此,如:Kmeans、Matrix Factorization等等

27

Page 28: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

4 Stata FOR ECONOMETRIC

利⽤ Stata做計量分析或實證很簡單,你只要會 reg y x1 x2就夠了 (開玩笑的)。這節會談到在 Stata上執⾏計量⽅法 (如:線性迴歸、Panel Data Model等)、相關的檢定以及輸出結果。重點還是會放在 Stata的操作上,但也許會附帶地提到⼀些計量的概念。最後,也許我應該強調⼀下:對計量或實證⽽⾔,Stata上的操作終究只是⼯具⽽已,清楚地了解⾃⼰在估計什麼,有邏輯地選擇⽅法與詮釋比起跑了幾百幾千條迴歸更重要。

4.1 Linear Regression

學過統計的⼈想必對線性迴歸 (Linear Regression)不陌⽣,再開始談 Stata上線性迴歸的操作時,不妨先想想看線性迴歸是什麼?

• 線性迴歸是⼀種以極⼩化Mean Square Error(MSE)的⽅式來 fit data。

• 在某些假設之下,線性迴歸的參數可以「⼀致地」估計出我們所想像的 X與 y的關係。

• 從幾何與線性代數上看來,迴歸不過是把向量 y(長度為 n),投影到樣本矩陣 Xn,k 的

k維欄空間上。

• 從 Stata上看來,迴歸不過是 reg <y> <x_list>, <options>罷了。其中的 <y>是依變數,<x_list>則是⾃變數。

⼀般來說, reg的指令基本上沒什麼困難,但我們仍然可以在推論 (inference) 或檢定(hypothese test)時做⼀些調整,像是使⽤ robust standard error(robust to heteroscedasticityor autocorrelation)。另外,有時候我們的 <x_list>需要包括⼆元或類別變數,或者是變數間的交乘項。⼀些⽅便的 operator可以幫我們達成這些⽬的,⽽不需要花時間⽣成變數。以下條列⼀些說明

• Option , robust或 , r可以使⽤異質變異數 robust的標準誤於 β ⾝上。

• Option , noconstant可以忽略掉迴歸中的常數項。請注意,再沒有常數項的情形下,R2 的定義可能和平常的不太⼀樣。

• 在 <x_list>之中, i.<var>等同於將 <var>類別化之後放入迴歸式。當然,Stata會⾃動幫我們挑⼀組作為「base group」以避免 dummy trap。此外, b<val>.<var>可以更改 base group為 <val>。

• i.<var>⼜稱 factor variable,在放入 factor variable 時,如果在迴歸指令前⽅加上prefix xi:,就會順便依照 <var>的每個類別⽣成 dummy。

• i.<v1>##i.<v2>可以⽣成 <v1>與 <v2>所組合出來的類別 (或說,<v1>與 <v2>的主效果以及交互作⽤)。

• 其中⼀個交成的變數是連續型的話,可以使⽤ c.<v2>。

28

Page 29: PracticalStatanoteshomepage.ntu.edu.tw/~r08a21037/print_pdf/Yeh...PracticalStatanotes 葉政維 NTUEcon 2018913 在開始本筆記之前,我想先做個簡單的 我介紹和寫作動機。本

• reg基本上會⾃動處理 multicollinearity,也就是會⾃動 omit掉多餘的變數。

當跑完迴歸後,也許我們最常做的就是各種假設檢定。如果只是要看某個參數是否

顯著的話,回傳的報表就已經有了。但我們可以再利⽤ test或是 lincom來檢定⼀些線性的限制條件,例如 H0 : β1 + β2 = 0;β3 = 1。此外,我們還可以根據剛跑出來,熱騰騰的迴

歸模型去做 fitting(當然,不⼀定要 fit在同⼀組資料上),也就是回傳每個樣本點的預測值。相關說明條列於下

• test <varlsit>,可以同時檢定 <varlist>中的每個 <var>是否為零

• test (<res>) (<res>) ...,可以同時檢定數個線性的限制式 <res>,<res>可以是某種<expression>,例如 <var1> + <var2> = 0、<var3> = 1。

• lincom <res>,可以檢定某「個」線性的限制式,但這邊的 <res>要表⽰為:限制式等號左邊為 0時,等號右半邊的部分,例如:<var3> - 1。

• predict <var>, <pred>,使⽤現有的模型來 fit樣本點。<var>是⽤來存 fitted value的新變數,⽽ <pred>則是要 fit的⽬標,比如說 xb就是 fit y,⽽ resid則是 fit殘差項 u。

• 請注意,上述這些指令都需要在估計指令 (如 reg )之後使⽤。如果重新跑了新的迴歸,舊的結果就會被覆蓋掉。32

線性迴歸也就差不多如此了,最後再補充⼀些取得迴歸資訊的好⽅法

• 2-8有提到多數指令執⾏之後,會有⼀個 return list來記錄⼀些訊息。對於那些「估計指令」來說,有⼀個 ereturn list來記估計模型的⼀些資訊,例如參數的估計值與變異數矩陣、Sum Square Error等。

• 除了 ereturn list之外。我們還可以藉由 _b[<var>]、 _se[<var>],來取得某⾃變數<var>的估計係數與標準誤。

4.2 Output

這⼩節會談到如何將迴歸結果輸出成 word上的圖表,或者是像.xls、.tex等形式。就我所知,「outreg2」、「estout」是最常使⽤的兩個輸出圖表⽤的套件,前者較為簡單,⽽後者使⽤上比較彈性。

32有興趣想看看怎麼暫存或叫回先前估計結果的⼈,可以參考 estimates 系列的指令

29