1. 程式人生 > >Stata資料處理: 面板資料填充和補漏

Stata資料處理: 面板資料填充和補漏

Stata連享會 (知乎 | 簡書 | 碼雲)

Stata連享會 精彩推文1 || 精彩推文2

Source: http://www.statalist.org/forums/forum/general-stata-discussion/general/17996-substitute-rows-with-average-of-row-above-and-below

文章目錄

問題描述

我有一份面板資料,有些年份上的資料有兩行或多行記錄 (例如,本例中 2007 年的資料)。棘手的是,這兩行資料存在差異,且無法判斷哪一個記錄是正確的。此時,比較穩妥的選擇是:將這兩漢資料都捨棄,使用相鄰年度 (2006 和 2008 年) 的均值作為 2007 年的觀察值 (插值)。

clear
input ID    year    var1    var2    var3
1    2006    34    45    65
1    2007    45    43    41
1    2007    3    56    59
1    2008    39    54    76
1    2009    41    57    68
end
save "data00.dta", replace

原始資料詳情:

. list

     +--------------------------------+
     | ID   year   var1   var2   var3 |
     |--------------------------------|
  1. |  1   2006     34     45     65 |
  2. |  1   2007     45     43     41 |
  3. |  1   2007      3     56     59 |
  4. |  1   2008     39     54     76 |
  5. |  1   2009     41     57     68 |
     +--------------------------------+


解決方法1: 使用 tssmooth ma 命令

思路:

  • 先刪除重複的觀察值 (2007 年的資料)
  • 繼而使用 tsfill 填充年份,讓資料變成平行面板;
  • 最後用 tssmooth ma 命令插值 (用前後兩年的平均值代替 2007 年的缺失值)。
    說明:此處 mamoving average 的簡寫。

命令如下:

. use "data00.dta", clear
*-刪除重複值  (資料有誤)
. drop if year == 2007
. tsset ID year
. tsfill
. list
     +--------------------------------+
     | ID   year   var1   var2   var3 |
     |--------------------------------|
  1. |  1   2006     34     45     65 |
  2. |  1   2007      .      .      . |
  3. |  1   2008     39     54     76 |
  4. |  1   2009     41     57     68 |
     +--------------------------------+
*-填充缺失值:
forv i = 1/3 {
    tssmooth ma v`i' = var`i' , w(1, 0, 1)
    replace var`i' = v`i' if var`i' == .
}
drop v?
list

執行結果如下:

. forv i = 1/3 {
  2.     tssmooth ma v`i' = var`i' , w(1, 0, 1)
  3.     replace var`i' = v`i' if var`i' == .
  4. }
The smoother applied was
     (1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var1
(1 real change made)
The smoother applied was
     (1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var2
(1 real change made)
The smoother applied was
     (1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var3
(1 real change made)

. drop v?

. list
     +--------------------------------+
     | ID   year   var1   var2   var3 |
     |--------------------------------|
  1. |  1   2006     34     45     65 |
  2. |  1   2007   36.5   49.5   70.5 |
  3. |  1   2008     39     54     76 |
  4. |  1   2009     41     57     68 |
     +--------------------------------+

從結果的提示資訊可以看出 w(1, 0, 1) 選項的含義:

The smoother applied was
     (1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var1


解決方法2: 使用 duplicates tag 命令

思路:

  • 使用 duplicates tag 命令標記重複的觀察值,並使用 gen() 選項產生新變數用以記錄標記情況;
  • 刪除重複的觀察值 (其實,這兩步可以合為一步);
  • 使用 _n 標記觀察先後順序 (x[_n] 表示 x t x_{t}; x[_n-1] 表示 x t 1 x_{t-1} x[_n+1] 表示 x t + 1 x_{t+1} ),進行插值;
clear
input id year var1 var2 var3
1 2006 34 45 65
1 2007 45 43 41
1 2007 3 56 59
1 2008 39 54 76
1 2009 41 57 68
end

使用 duplicates tag 標記重複的觀察值:

. duplicates tag id year, gen(mistake)  
. list
. bysort id year: keep if (_n == 1)
  foreach v of varlist var1 var2 var3 {  
     replace `v' =  (`v'[_n-1] + `v'[_n+1])/2 if mistake
  }

結果如下:

.  duplicates tag id year, gen(mistake)  
Duplicates in terms of id year

.  list   // A-1
     +------------------------------------------+
     | id   year   var1   var2   var3   mistake |
     |------------------------------------------|
  1. |  1   2006     34     45     65         0 |
  2. |  1   2007     45     43     41         1 |
  3. |  1   2007      3     56     59         1 |
  4. |  1   2008     39     54     76         0 |
  5. |  1   2009     41     57     68         0 |
     +------------------------------------------+

.  bysort id year: keep if (_n == 1)
(1 observation deleted)

.  list   // A-2
     +------------------------------------------+
     | id   year   var1   var2   var3   mistake |
     |------------------------------------------|
  1. |  1   2006     34     45     65         0 |
  2. |  1   2007     45     43     41         1 |
  3. |  1   2008     39     54     76         0 |
  4. |  1   2009     41     57     68         0 |
     +------------------------------------------+

.  foreach v of varlist var1 var2 var3 {  
  2.     replace `v' =  (`v'[_n-1] + `v'[_n+1])/2 if mistake
  3.  }

.  list   // A-3
     +------------------------------------------+
     | id   year   var1   var2   var3   mistake |
     |------------------------------------------|
  1. |  1   2006     34     45     65         0 |
  2. |  1   2007   36.5   49.5   70.5         1 |
  3. |  1   2008     39     54     76         0 |
  4. |  1   2009     41     57     68         0 |
     +------------------------------------------+


附:文中使用的程式碼

*------------
*-Solution 1:
* You could use tssmooth ma.
* For example:

clear
input ID    year    var1    var2    var3
1    2006    34    45    65
1    2007    45    43    41
1    2007    3    56    59
1    2008    39    54    76
1    2009    41    57    68
end

list

drop if year == 2007
tsset ID year
tsfill
list 

forv i = 1/3 {
    tssmooth ma v`i' = var`i' , w(1, 0, 1)
    replace var`i' = v`i' if var`i' == .
}
drop v?
list

*------------
*-Solution 2:  

clear
input id year var1 var2 var3
1 2006 34 45 65
1 2007 45 43 41
1 2007 3 56 59
1 2008 39 54 76
1 2009 41 57 68
end

duplicates tag id year, gen(mistake)  
list
bysort id year: keep if (_n == 1)
list
foreach v of varlist var1 var2 var3 {  
   replace `v' =  (`v'[_n-1] + `v'[_n+1])/2 if mistake
}
list

關於我們

  • Stata 連享會(公眾號:StataChina)】由中山大學連玉君老師團隊創辦,旨在定期與大家分享 Stata 應用的各種經驗和技巧。
  • 公眾號推文同步釋出於 CSDN-Stata連享會簡書-Stata連享會知乎-連玉君Stata專欄。可以在上述網站中搜索關鍵詞StataStata連享會後關注我們。
  • 點選推文底部【閱讀原文】可以檢視推文中的連結並下載相關資料。
  • Stata連享會 精彩推文1 || 精彩推文2

聯絡我們

  • 歡迎賜稿: 歡迎將您的文章或筆記投稿至Stata連享會(公眾號: StataChina),我們會保留您的署名;錄用稿件達五篇以上,即可免費獲得 Stata 現場培訓 (初級或高階選其一) 資格。
  • 意見和資料: 歡迎您的寶貴意見,您也可以來信索取推文中提及的程式和資料。
  • 招募英才: 歡迎加入我們的團隊,一起學習 Stata。合作編輯或撰寫稿件五篇以上,即可免費獲得 Stata 現場培訓 (初級或高階選其一) 資格。
  • 聯絡郵件: [email protected]

往期精彩推文


歡迎加入Stata連享會(公眾號: StataChina)