查看原文
其他

Stata数据处理: 面板数据填充和补漏

stata连享会 Stata连享会 2020-02-10

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


本期责任编辑:王俊



Stata现场班 (2019.1.17-27) 课程详情


Stata寒假精品现场班(1月17日-27日)报名主页


开始接受报名


问题描述

我有一份面板数据,有些年份上的数据有两行或多行记录 (例如,本例中 2007 年的数据)。棘手的是,这两行数据存在差异,且无法判断哪一个记录是正确的。此时,比较稳妥的选择是:将这两汉数据都舍弃,使用相邻年度 (2006 和 2008 年) 的均值作为 2007 年的观察值 (插值)。

  1. clear

  2. input ID    year    var1    var2    var3

  3. 1    2006    34    45    65

  4. 1    2007    45    43    41

  5. 1    2007    3    56    59

  6. 1    2008    39    54    76

  7. 1    2009    41    57    68

  8. end

  9. save "data00.dta", replace

原始数据详情:

  1. . list


  2.     +--------------------------------+

  3.     | ID   year   var1   var2   var3 |

  4.     |--------------------------------|

  5.  1. |  1   2006     34     45     65 |

  6.  2. |  1   2007     45     43     41 |

  7.  3. |  1   2007      3     56     59 |

  8.  4. |  1   2008     39     54     76 |

  9.  5. |  1   2009     41     57     68 |

  10.     +--------------------------------+


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

思路:

  • 先删除重复的观察值 (2007 年的数据)

  • 继而使用 tsfill 填充年份,让数据变成平行面板;

  • 最后用 tssmooth ma 命令插值 (用前后两年的平均值代替 2007 年的缺失值)。
    说明:此处 mamoving average 的简写。

命令如下:

  1. . use "data00.dta", clear

  2. *-删除重复值  (数据有误)

  3. . drop if year == 2007

  4. . tsset ID year

  5. . tsfill

  6. . list

  7.     +--------------------------------+

  8.     | ID   year   var1   var2   var3 |

  9.     |--------------------------------|

  10.  1. |  1   2006     34     45     65 |

  11.  2. |  1   2007      .      .      . |

  12.  3. |  1   2008     39     54     76 |

  13.  4. |  1   2009     41     57     68 |

  14.     +--------------------------------+

  15. *-填充缺失值:

  16. forv i = 1/3 {

  17.    tssmooth ma v`i' = var`i' , w(1, 0, 1)

  18.    replace var`i' = v`i' if var`i' == .

  19. }

  20. drop v?

  21. list

运行结果如下:

  1. . forv i = 1/3 {

  2.  2.     tssmooth ma v`i' = var`i' , w(1, 0, 1)

  3.  3.     replace var`i' = v`i' if var`i' == .

  4.  4. }

  5. The smoother applied was

  6.     (1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var1

  7. (1 real change made)

  8. The smoother applied was

  9.     (1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var2

  10. (1 real change made)

  11. The smoother applied was

  12.     (1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var3

  13. (1 real change made)


  14. . drop v?


  15. . list

  16.     +--------------------------------+

  17.     | ID   year   var1   var2   var3 |

  18.     |--------------------------------|

  19.  1. |  1   2006     34     45     65 |

  20.  2. |  1   2007   36.5   49.5   70.5 |

  21.  3. |  1   2008     39     54     76 |

  22.  4. |  1   2009     41     57     68 |

  23.     +--------------------------------+

从结果的提示信息可以看出 w(1, 0, 1) 选项的含义:

  1. The smoother applied was

  2.     (1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var1


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

思路:

  • 使用 duplicates tag 命令标记重复的观察值,并使用 gen() 选项产生新变量用以记录标记情况;

  • 删除重复的观察值 (其实,这两步可以合为一步);

  • 使用 _n 标记观察先后顺序 (x[_n] 表示 x[_n-1] 表示x[_n+1] 表示 ),进行插值;

  1. clear

  2. input id year var1 var2 var3

  3. 1 2006 34 45 65

  4. 1 2007 45 43 41

  5. 1 2007 3 56 59

  6. 1 2008 39 54 76

  7. 1 2009 41 57 68

  8. end

使用 duplicates tag 标记重复的观察值:

  1. . duplicates tag id year, gen(mistake)  

  2. . list

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

  4.  foreach v of varlist var1 var2 var3 {  

  5.     replace `v' =  (`v'[_n-1] + `v'[_n+1])/2 if mistake

  6.  }

结果如下:

  1. .  duplicates tag id year, gen(mistake)  

  2. Duplicates in terms of id year


  3. .  list   // A-1

  4.     +------------------------------------------+

  5.     | id   year   var1   var2   var3   mistake |

  6.     |------------------------------------------|

  7.  1. |  1   2006     34     45     65         0 |

  8.  2. |  1   2007     45     43     41         1 |

  9.  3. |  1   2007      3     56     59         1 |

  10.  4. |  1   2008     39     54     76         0 |

  11.  5. |  1   2009     41     57     68         0 |

  12.     +------------------------------------------+


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

  14. (1 observation deleted)


  15. .  list   // A-2

  16.     +------------------------------------------+

  17.     | id   year   var1   var2   var3   mistake |

  18.     |------------------------------------------|

  19.  1. |  1   2006     34     45     65         0 |

  20.  2. |  1   2007     45     43     41         1 |

  21.  3. |  1   2008     39     54     76         0 |

  22.  4. |  1   2009     41     57     68         0 |

  23.     +------------------------------------------+


  24. .  foreach v of varlist var1 var2 var3 {  

  25.  2.     replace `v' =  (`v'[_n-1] + `v'[_n+1])/2 if mistake

  26.  3.  }


  27. .  list   // A-3

  28.     +------------------------------------------+

  29.     | id   year   var1   var2   var3   mistake |

  30.     |------------------------------------------|

  31.  1. |  1   2006     34     45     65         0 |

  32.  2. |  1   2007   36.5   49.5   70.5         1 |

  33.  3. |  1   2008     39     54     76         0 |

  34.  4. |  1   2009     41     57     68         0 |

  35.     +------------------------------------------+


附:文中使用的代码

  1. *------------

  2. *-Solution 1:

  3. * You could use tssmooth ma.

  4. * For example:


  5. clear

  6. input ID    year    var1    var2    var3

  7. 1    2006    34    45    65

  8. 1    2007    45    43    41

  9. 1    2007    3    56    59

  10. 1    2008    39    54    76

  11. 1    2009    41    57    68

  12. end


  13. list


  14. drop if year == 2007

  15. tsset ID year

  16. tsfill

  17. list


  18. forv i = 1/3 {

  19.    tssmooth ma v`i' = var`i' , w(1, 0, 1)

  20.    replace var`i' = v`i' if var`i' == .

  21. }

  22. drop v?

  23. list


  24. *------------

  25. *-Solution 2:  


  26. clear

  27. input id year var1 var2 var3

  28. 1 2006 34 45 65

  29. 1 2007 45 43 41

  30. 1 2007 3 56 59

  31. 1 2008 39 54 76

  32. 1 2009 41 57 68

  33. end


  34. duplicates tag id year, gen(mistake)  

  35. list

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

  37. list

  38. foreach v of varlist var1 var2 var3 {  

  39.   replace `v' =  (`v'[_n-1] + `v'[_n+1])/2 if mistake

  40. }

  41. list

关于我们

  • Stata 连享会(公众号:StataChina)】由中山大学连玉君老师团队创办,旨在定期与大家分享 Stata 应用的各种经验和技巧。

  • 公众号推文同步发布于 CSDN-Stata连享会 、简书-Stata连享会 和 知乎-连玉君Stata专栏。可以在上述网站中搜索关键词StataStata连享会后关注我们。

  • 点击推文底部【阅读原文】可以查看推文中的链接并下载相关资料。

  • Stata连享会 精彩推文1  || 精彩推文2

联系我们

  • 欢迎赐稿: 欢迎将您的文章或笔记投稿至Stata连享会(公众号: StataChina),我们会保留您的署名;录用稿件达五篇以上,即可免费获得 Stata 现场培训 (初级或高级选其一) 资格。

  • 意见和资料: 欢迎您的宝贵意见,您也可以来信索取推文中提及的程序和数据。

  • 招募英才: 欢迎加入我们的团队,一起学习 Stata。合作编辑或撰写稿件五篇以上,即可免费获得 Stata 现场培训 (初级或高级选其一) 资格。

  • 联系邮件: StataChina@163.com

往期精彩推文


 


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存