# Stata：如何保留时间连续的样本

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

## 1. 问题引出

``````*-输入数据
clear
input id year price
1 2000 12
1 2001 23
1 2003 12
1 2004 13
1 2005 14
2 2000 44
2 2001 34
2 2002 67
3 2000 32
3 2004 55
3 2005 46
4 2000 34
4 2001 87
4 2002 78
4 2004 89
4 2005 99
5 2000 34
5 2002 77
5 2004 88
6 2001 14
6 2002 27
6 2003 38
end
xtset id year
save lianxh_xt_conti.dta, replace

*-样本分布
use lianxh_xt_conti.dta, clear
xtset id year
xtdes
``````

``````    Freq.  Percent    Cum. |  Pattern
---------------------------+---------
1     16.67   16.67 |  .111..
1     16.67   33.33 |  1...11
1     16.67   50.00 |  1.1.1.
1     16.67   66.67 |  11.111
1     16.67   83.33 |  111...
1     16.67  100.00 |  111.11
---------------------------+---------
6    100.00         |  XXXXXX
``````

Note: 本文主要介绍如何将包含有连续三年的样本筛选出来，若仅要保留连续三年数据，只需调整部分参数。

## 2. 方法 1：bysort 的运用

``````*-bysort
use lianxh_xt_conti.dta, clear
gen ss = 0
by id (year), sort: replace ss = 1 if year - year[_n-2] == 2
by id (year), sort: egen ss_sum = sum(ss)
list in 1/11, sepby(id) noobs
keep if ss_sum > 0
xtdes
``````

`````` +---------------------------------+
| id   year   price   ss   ss_sum |
|---------------------------------|
|  1   2000      12    0        1 |
|  1   2001      23    0        1 |
|  1   2003      12    0        1 |
|  1   2004      13    0        1 |
|  1   2005      14    1        1 |
|---------------------------------|
|  2   2000      44    0        1 |
|  2   2001      34    0        1 |
|  2   2002      67    1        1 |
|---------------------------------|
|  3   2000      32    0        0 |
|  3   2004      55    0        0 |
|  3   2005      46    0        0 |
+---------------------------------+
``````
``````     Freq.  Percent    Cum. |  Pattern
---------------------------+---------
1     25.00   25.00 |  .111..
1     25.00   50.00 |  11.111
1     25.00   75.00 |  111...
1     25.00  100.00 |  111.11
---------------------------+---------
4    100.00         |  XXXXXX
``````

## 3. 方法 2：xtpattern 的应用

`xtpattern` 命令根据面板数据出现的时间创建字符串，我们可以依此筛选需要的样本。具体代码如下：

``````*-xtpattern
use lianxh_xt_conti.dta, clear
xtpattern, gen(pp)
gen ss = strpos(pp, "111")
list in 1/11, sepby(id) noobs
keep if ss > 0
xtdes
``````

``````     Freq.  Percent    Cum. |  Pattern
---------------------------+---------
1     25.00   25.00 |  .111..
1     25.00   50.00 |  11.111
1     25.00   75.00 |  111...
1     25.00  100.00 |  111.11
---------------------------+---------
4    100.00         |  XXXXXX
``````

`xtpattern` 命令注意事项：

• `xtpattern` 对象为面板数据，所以在使用该命令前需 `xtset`
• 若当年有数据，取值为 1，反之为 .，字符串长度是根据样本中最长年份确定的。

## 4. 方法 3：tsspell 的应用

``````*-tsspell
use lianxh_xt_conti.dta, clear
xtset id year
tsspell, f(L.year == .)
by id: egen maxrun = max(_seq)
list in 1/11, sepby(id) noobs
keep if maxrun >= 3
xtdes
``````

``````  +---------------------------------------------------+
| id   year   price   _spell   _seq   _end   maxrun |
|---------------------------------------------------|
|  1   2000      12        1      1      0        3 |
|  1   2001      23        1      2      1        3 |
|  1   2003      12        2      1      0        3 |
|  1   2004      13        2      2      0        3 |
|  1   2005      14        2      3      1        3 |
|---------------------------------------------------|
|  2   2000      44        1      1      0        3 |
|  2   2001      34        1      2      0        3 |
|  2   2002      67        1      3      1        3 |
|---------------------------------------------------|
|  3   2000      32        1      1      1        2 |
|  3   2004      55        2      1      0        2 |
|  3   2005      46        2      2      1        2 |
+---------------------------------------------------+
``````
``````     Freq.  Percent    Cum. |  Pattern
---------------------------+---------
1     25.00   25.00 |  .111..
1     25.00   50.00 |  11.111
1     25.00   75.00 |  111...
1     25.00  100.00 |  111.11
---------------------------+---------
4    100.00         |  XXXXXX
``````

`tsspell` 命令注意事项：

• 在使用 `tsspell` 命令前，必须先将数据设置为面板数据；
• `tsspell, f(L.year == .)` 是找出连续年份，详情可参考 `help tsspell`
• _seq 代表连续年份顺序；
• _end 代表是否是年份顺序最后一个；
• 最后，我们可通过找出 _seq 中最大值，找出连续三年的样本数据。

## 5. 方法 4：regress 的应用

### 5.1 方法一

``````*-regress 1
use "lianxh_xt_conti.dta", clear
xtset id year

reg id F(1/2).id
gen ss = e(sample)

bysort id: gen ss_sum  = sum(ss)
bysort id: gen ss_sum2 = sum(ss_sum)
list in 1/11, sepby(id) noobs
keep if ss_sum2 >= 1 & ss_sum2 <= 3
xtdes
``````

``````  +-------------------------------------------+
| id   year   price   ss   ss_sum   ss_sum2 |
|-------------------------------------------|
|  1   2000      12    0        0         0 |
|  1   2001      23    0        0         0 |
|  1   2003      12    1        1         1 |
|  1   2004      13    0        1         2 |
|  1   2005      14    0        1         3 |
|-------------------------------------------|
|  2   2000      44    1        1         1 |
|  2   2001      34    0        1         2 |
|  2   2002      67    0        1         3 |
|-------------------------------------------|
|  3   2000      32    0        0         0 |
|  3   2004      55    0        0         0 |
|  3   2005      46    0        0         0 |
+-------------------------------------------+
``````
``````     Freq.  Percent    Cum. |  Pattern
---------------------------+---------
2     50.00   50.00 |  111...
1     25.00   75.00 |  ...111
1     25.00  100.00 |  .111..
---------------------------+---------
4    100.00         |  XXXXXX
``````

### 5.2 方法二

``````  use "lianxh_xt_conti.dta", clear
xtset id year

qui reg id F(1/2).id
gen s1 = e(sample)
list, sepby(id)

qui reg id L(1).id F1.id
gen s2 = e(sample)
list, sepby(id)

qui reg id L(1/2).id
gen s3 = e(sample)
list, sepby(id)

gen ss = s1+s2+s3
list in 1/11, sepby(id) noobs

by id: egen ss_sum = sum(ss)
keep if ss_sum == 3
xtdes
``````
``````  +---------------------------------------+
| id   year   price   s1   s2   s3   ss |
|---------------------------------------|
|  1   2000      12    0    0    0    0 |
|  1   2001      23    0    0    0    0 |
|  1   2003      12    1    0    0    1 |
|  1   2004      13    0    1    0    1 |
|  1   2005      14    0    0    1    1 |
|---------------------------------------|
|  2   2000      44    1    0    0    1 |
|  2   2001      34    0    1    0    1 |
|  2   2002      67    0    0    1    1 |
|---------------------------------------|
|  3   2000      32    0    0    0    0 |
|  3   2004      55    0    0    0    0 |
|  3   2005      46    0    0    0    0 |
+---------------------------------------+
``````
``````     Freq.  Percent    Cum. |  Pattern
---------------------------+---------
1     25.00   25.00 |  .111..
1     25.00   50.00 |  11.111
1     25.00   75.00 |  111...
1     25.00  100.00 |  111.11
---------------------------+---------
4    100.00         |  XXXXXX
``````

## 相关课程

http://lianxh.duanshu.com

### 课程一览

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

#### 关于我们

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

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