我在 R 和 Python 中看到过这方面的问题(例如,NA 仅当使用 dplyr“夹在”相同的值时才填充),但无法在 Stata 中找到如何执行此操作的答案。
我只想在面板数据集中填充缺失值,前提是它介于 2 个相等的非缺失值之间。例如,如果我有
clear
input score group
2005 1
2006 .
2007 .
2008 .
2009 1
2010 8
2011 1
2012 .
2013 5
2014 3
2015 4
end
2006年、2007年、2008年的缺失值会被补成1,2012年的缺失值不会被补上。缺失值是分类的,不是有序的。
如果前一个值和下一个值相等,我尝试用前一个值填充,但这不考虑两个相等的非缺失值之间夹着超过 1 个缺失的情况。
编辑:下面提供的解决方案在某些情况下有效,但在其他情况下却出乎意料(我更改了一些变量名称以使其更直观,并在一个块中包含两个示例)。假设我从
开始clear
input year group id
2005 1 1
2006 1 .
2007 1 .
2008 1 .
2009 1 .
2010 1 .
2011 1 1
2007 2 3
2008 2 .
2009 2 .
2010 2 2
2011 2 2
end
使用解决方案,有时我会得到
clear
input year group id
2005 1 1
2006 1 .
2007 1 .
2008 1 .
2009 1 .
2010 1 .
2011 1 1
2007 2 3
2008 2 3
2009 2 3
2010 2 2
2011 2 2
end
第一组,非缺失者该填的时候没填。对于第 2 组,他们确实填写了但不应该填写,因为三明治末端的非缺失值不相等。
这是一种方法。
插值或插补的一种方法就是将最后一个已知值向前推进。在 Stata 中,这在 https://www.stata.com/support/faqs/data-management/replacing-missing-values/
中进行了讨论另一种方法是线性插值。当且仅当插值是平坦的时,线性插值将产生与方法 1 相同的答案,以便插值在每一端等于已知值。
毫无疑问,您可以插值并检查稳定性,但我的猜测是,这将与此处给出的代码一样多。
clear
input score group
2005 1
2006 .
2007 .
2008 .
2009 1
2010 8
2011 1
2012 .
2013 5
2014 3
2015 4
end
clonevar guess1 = group
replace guess1 = guess1[_n-1] if missing(guess1)
ipolate group score, gen(guess2)
gen goodguess = guess1 if guess1 == guess2
list, sepby(goodguess)
+--------------------------------------------+
| score group guess1 guess2 goodgu~s |
|--------------------------------------------|
1. | 2005 1 1 1 1 |
2. | 2006 . 1 1 1 |
3. | 2007 . 1 1 1 |
4. | 2008 . 1 1 1 |
5. | 2009 1 1 1 1 |
|--------------------------------------------|
6. | 2010 8 8 8 8 |
|--------------------------------------------|
7. | 2011 1 1 1 1 |
|--------------------------------------------|
8. | 2012 . 1 3 . |
|--------------------------------------------|
9. | 2013 5 5 5 5 |
|--------------------------------------------|
10. | 2014 3 3 3 3 |
|--------------------------------------------|
11. | 2015 4 4 4 4 |
+--------------------------------------------+
你提到面板数据没有举例说明,但这种方法可以很容易地扩展到面板数据。根据需要使用
by:
或 by()
选项。
编辑有关变量是分类的而不是序数的最新细节(意思是,名义上不是序数;许多(如果不是大多数的话)当局将“序数”视为一种分类;见证 Alan Agresti 的文本)不会影响此处的解决方案。向下复制的方法永远不会建议不同的类别。
ipolate
将数据视为线性插值有意义;当它建议一个不可接受的替换值时,上面的代码将不会接受它。
EDIT 2 你得到了你不想要的结果,因为你正在将一个问题的代码应用到另一个完全不同的问题。显然涉及三个变量,而不是两个,这与最初的问题相反。在那种情况下,代码应该不同。
clear
input year group id
2005 1 1
2006 1 .
2007 1 .
2008 1 .
2009 1 .
2010 1 .
2011 1 1
2007 2 3
2008 2 .
2009 2 .
2010 2 2
2011 2 2
end
clonevar guess1 = id
bysort group (year) : replace guess1 = guess1[_n-1] if missing(guess1)
ipolate id year, gen(guess2) by(group)
gen goodguess = guess1 if guess1 == guess2
换句话说,最初的答案是从给出的例子中得出的,在这个例子中观察是按
year
顺序并且没有分组变量;因此对于每个不同的year
只有一个观察。
当有其他结构(例如面板或纵向数据)时,您需要其他代码来匹配它。