# Stata数据处理：面板数据的填充和补漏

Stata 连享会   主页 || 视频 || 推文

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

## 问题描述

``````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
The smoother applied was
(1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var2
The smoother applied was
(1/2)*[x(t-1) + 0*x(t) + x(t+1)]; x(t)= var3

. 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 |
+--------------------------------+
``````

``````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[_n-1] 表示 ${x}_{t-1}$x[_n+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 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
``````

## 相关课程

http://lianxh.duanshu.com

### 课程一览

Stata数据清洗 游万海 直播, 2 小时，已上线

Note: 部分课程的资料，PPT 等可以前往 连享会-直播课 主页查看，下载。

#### 关于我们

• Stata连享会 由中山大学连玉君老师团队创办，定期分享实证分析经验。直播间 有很多视频课程，可以随时观看。
• 连享会-主页知乎专栏，300+ 推文，实证分析不再抓狂。
• 公众号推文分类： 计量专题 | 分类推文 | 资源工具。推文分成 内生性 | 空间计量 | 时序面板 | 结果输出 | 交乘调节 五类，主流方法介绍一目了然：DID, RDD, IV, GMM, FE, Probit 等。
• 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标，输入简要关键词，以便快速呈现历史推文，获取工具软件和数据下载。常见关键词：`课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法`

✏ 连享会学习群-常见问题解答汇总：
https://gitee.com/arlionn/WD