附件:

  • 【附件内容】do文件,PDF笔记,录屏
  • 【附件下载】链接:https://pan.baidu.com/s/1GNT1PwtE3TzEHaaL4TLP9g?pwd=e8zw

本文是教对象Stata系列视频的笔记内容。对应视频与配套代码请见下方链接,笔记内容请见分割线下方。

视频合集

bilibili视频链接

配套代码链接


一、使用 reshape 命令

  将竖向的列变为横向的行,即为“长转宽”;将横的行变为竖向的列,即为“宽转长”。在 Stata 中,通过 reshape 命令可以实现长宽数据转换。

1. 基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
** 宽数据转化为长数据 (wide to long)
reshape long stubnames, i(varlist) [options]

** 长数据转化为宽数据 (long to wide)
reshape wide stubnames, i(varlist) [options]

** 长宽数据转换失败时,列出转换失败的样本
reshape error

/* Note: stubnames 表示变量前缀名;
i(varlist): varlist 是宽数据中可以唯一识别每组样本的变量,如家庭数据中的家庭编码;
j(varname): varname 是在长数据中,根据宽数据唯一识别码的分组后,每组中每个样本的识别码,如家庭成员数据中的成员顺序码;
string: 长宽数据转换时,j(varname) 中的 varlist 不是数值时,需要使用string;不特别指定,默认是数值。 */

2. 图示

1
2
3
4
5
6
7
8
9
10
11
/* reshape 示例:
long data
+-----------------+ wide data
| id j x y | +--------------------------+
|-----------------| | id x1 x2 x3 y |
| 1 1 4.1 1 | reshape |--------------------------|
| 1 2 4.5 1 | <---------> | 1 4.1 4.5 . 1 |
| 2 1 3.3 3 | | 2 3.3 3 5.5 3 |
| 2 2 3 3 | +--------------------------+
| 2 3 5.5 3 |
+-----------------+ */

  常见情况:

  家庭数据中,家庭编码 ID 可以唯一识别每一个家庭样本,每个家庭成员在家庭内有唯一顺序码 PID,用家庭编码 ID 和家庭内顺序码 PID 可以唯一识别每个家庭成员。

  注意事项:

  • 适用于树状数据的跨层级关系。

  • wide --> long:

    • i(varlist) 唯一识别每个样本;
    • 需要指定被转换的变量,未被指定的变量,将会根据 i(varlist) 分组后复制到组内样本中。
  • long --> wide:

    • i(varlist)j(varname) 共同唯一识别每个样本。
    • 需要指定被转换的变量,未被转换的变量,根据 i(varlist) 分组后,组内每个样本的取值应该相同,否则无法转换成功。
  • j(varname) 是字符型变量时,需要使用 string 选项才能转换成功。

3. 示例

1
2
3
4
5
6
7
** wide to long: X1_1 X1_2 X2_1 X2_2 --> X1 X2
reshape long X1 X2,i(ID) j(PID) string
** Note: 每个样本的唯一识别码是ID,需要转换的变量是X1*、X2*(星号表示通配符),可将X1_1 X1_2转换为X1,并将"_1"和"_2"作为新生成变量PID的值,PID不是数值型,因此需要加上string选项。

** long to wide (长数据转化为宽数据)
reshape wide X1 X2,i(ID) j(PID) string
** Note: 转换为宽数据后,ID应作为唯一识别码,需要将X1、X2转换为X1*、X2*,其中*是对应PID的取值。若PID不是数值型,应当加上string。

  组合命令示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
** wide to long
reshape long X1,i(ID) j(PID) string //将X1_1 ~ X1_5转化为长数据
** 将PID转为数值型(方法一)
forvalues i=1/5 {
replace PID="`i'" if PID=="_`i'"
}
destring PID, replace
** 将PID转为数值型(方法二)
destring PID, i(_) replace //i(_)表示忽略下划线,将其他数字转换为数值型。
/* Note: 转换结果: X1,PID取值为1~5。*/

** long to wide
** 将PID转为字符型
tostring PID,replace
replace PID="_"+PID
reshape wide X1,i(ID) j(PID) string
/* Note: 转换结果: X1_1 X1_2 X1_3 X1_4 X1_5。*/

二、其他命令: tidy 包

  除了 reshape 命令外,tidy 包提供的 gatherspread 命令,也可以实现长宽数据转换。

  • gather 可以将宽数据转化为长数据,功能相当于reshape long
  • spread 可以将长数据转化为宽数据,功能相当于reshape wide
  • 使用 reshepe 进行长宽数据转换时,需要变量命名规则一致。gatherspread 很好地解决了变量名无规律时不能使用 reshape 进行长宽数据转化的问题。

1. 安装

  安装 tidy 命令,仅首次使用需要安装。

1
ssc install tidy, replace

2. 基本语法

1
2
3
4
5
6
7
gather varlist , [variable(newvar) value(newvar) label(newvar)]
/* variable(newvar): 变量名转化后的新变量名; 默认是“variable”;
value(newvar): 变量取值生成的新变量名称; 默认为“value”;
label(newvar): 生成一个新变量来存储 varlist 的变量标签。 */

spread variable value , [label(varname)]
/* label(varname): 使用字符型变量 varname 为新变量构造变量标签。 */

3. 示例

(⚠️注意:不同设备的显示字体不同,可能会出现字符错位的现象。将错位的文本复制到其他文本编辑器 / Stata do 文件编辑器中,可以解决此问题。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
** 调用示范数据(发达国家教育经费占GDP比重)
sysuse educ99gdp.dta, clear
** 查看数据
+----------------------------------+
| country public private |
|----------------------------------|
1. | Australia .7 .7 |
2. | Britain .7 .4 |
3. | Canada 1.5 .9 |
4. | Denmark 1.5 .1 |
5. | France .9 .4 |
6. | Germany .9 .2 |
7. | Ireland 1.1 .3 |
8. | Netherlands 1 .4 |
9. | Sweden 1.5 .2 |
10. | United States 1.1 1.2 |
+----------------------------------+

** 转化为长数据
gather public private, variable(sector) value(edu)
** 转化结果
+-------------------------------+
| country sector edu |
|-------------------------------|
1. | Australia public .7 |
2. | Australia private .7 |
3. | Britain public .7 |
4. | Britain private .4 |
5. | Canada public 1.5 |
6. | Canada private .9 |
7. | Denmark public 1.5 |
8. | Denmark private .1 |
9. | France public .9 |
10. | France private .4 |
11. | Germany public .9 |
12. | Germany private .2 |
13. | Ireland public 1.1 |
14. | Ireland private .3 |
15. | Netherlands public 1 |
16. | Netherlands private .4 |
17. | Sweden public 1.5 |
18. | Sweden private .2 |
19. | United States public 1.1 |
20. | United States private 1.2 |
+-------------------------------+

** 使用 spread , 上述的长数据可以很简单地转化为宽数据
spread sector edu

  ‍