👇 连享会 · 推文导航 |
www.lianxh.cn
🍓 课程推荐:
连享会:2025 寒假班
嘉宾:连玉君(初级|高级);杨海生(前沿)
时间:2025 年 1 月 13-24 日
咨询:王老师 18903405450(微信)
作者
:李坤 (华南师范大学)
邮箱
:[email protected]
温馨提示:
文中链接在微信中无法生效。请点击底部
「阅读原文」
。或直接长按/扫描如下二维码,直达原文:
目录
1. 引言
在数据分析中,我们经常通过
reshape
命令将宽数据转换为长数据。关于
reshape
命令的详细介绍,可参考连享会推文「
reshape 命令一文读懂 (上)
」和「reshape 命令一文读懂 (下)」。但是,当数据量较大时,
reshape
命令非常耗时。为此,我们介绍一个快速实现转换的新命令
tolong
。
2. 命令简介
tolong
命令安装:
ssc install tolong, replace
tolong
命令语法:
tolong newvar = stubname [newvar = stubname ...] [, i(varlist) j(newvar) sort]
其中,
newvar
代表转换后的新变量。新变量名必须是原来变量名中的一部分,例如原变量名分别为
one1
、
one2
,则
newvar
可以设定为
one
。
stubname
代表需要转换的变量,可以是单个也可以是多个。如果为多个,则需要依次列出转换变量。其中,
-
stubname#
:如要转换的变量名称为
two1
、
two2
、
two3
,可直接使用
two#
代替;
-
stubname@
:如要转换的变量名称为
threea
、
threeb
、
threec
,则可直接使用
three@
代替;
-
stubname*
:与直接使用
stubname
的含义一样。
除此之外,
-
i(varlist)
代表 ID 变量,需要是唯一的。如果省略此选项,则 i 变量将被命名为 _i,且顺序为观察编号;
-
j(newvar)
为
stubname
子集的变量名。即代表变量
foura
、
fourb
、
fourc
中的 a、b 和 c。如果省略此选项,则 j 变量将被命名为 _j。
newvar
代表想要给 j 变量取的变量名称。例如想将值 a、b、c 命名为 year,则直接输入
j(year)
;
-
sort
代表在转换之后按照
i(varlist)
和
j(newvar)
变量上的数据进行排序,默认是按照
i(varlist)
变量的原始顺序排序。
3. 具体案例
我们先创建一个简单的宽面板数据,然后再介绍一下
tolong
命令的常用用法。
. clear
. set seed 1234 // 设定种子值
. set obs 2 // 设置两个观测值
. gen id = _n // 新增一个时间序列数
. gen x1 = rnormal() // 新增变量名为 x1 的标准正态分布随机数
. gen x2 = rnormal()
. gen xm = rnormal()
. gen xf = rnormal()
. list // 宽面板数据
. save tolong.dta, replace
+---------------------------------------------------+
| id x1 x2 xm xf |
|---------------------------------------------------|
1. | 1 -.4868504 -.0109115 .5155788 1.287317 |
2. | 2 -1.476004 -.0137603 -.1391217 -.587773 |
+---------------------------------------------------+
. preserve
. // 将宽数据转换成长数据, 同时未命名 j 变量
. // 该命令与 tolong x*, i(id) 以及 reshape long x, i(id) string 等价
. tolong x, i(id)
. list, sepby(id)
. restore
+---------------------+
| id _j x |
|---------------------|
1. | 1 1 -.4868504 |
2. | 1 2 -.0109115 |
3. | 1 f 1.287317 |
4. | 1 m .5155788 |
|---------------------|
5. | 2 1 -1.476004 |
6. | 2 2 -.0137603 |
7. | 2 f -.587773 |
8. | 2 m -.1391217 |
+---------------------+
tolong
命令中通配符的使用:
. preserve
. // 将宽的数字型数据转换成长面板数据, 未命名 j 变量
. // 该命令与 reshape long x, i(id) 等价, 只是变量的顺序不一样
. tolong x#, i(id)
. list, sepby(id)
. restore
+--------------------------------------------+
| id _j xm xf x |
|--------------------------------------------|
1. | 1 1 .5155788 1.287317 -.4868504 |
2. | 1 2 .5155788 1.287317 -.0109115 |
|--------------------------------------------|
3. | 2 1 -.1391217 -.587773 -1.476004 |
4. | 2 2 -.1391217 -.587773 -.0137603 |
+--------------------------------------------+
. preserve
. tolong x@, i(id) // 将宽的字符型数据转换成长面板数据
. list, sepby(id)
. restore
+---------------------------------------------+
| id _j x1 x2 x |
|---------------------------------------------|
1. | 1 f -.4868504 -.0109115 1.287317 |
2. | 1 m -.4868504 -.0109115 .5155788 |
|---------------------------------------------|
3. | 2 f -1.476004 -.0137603 -.587773 |
4. | 2 m -1.476004 -.0137603 -.1391217 |
+---------------------------------------------+
. preserve
. tolong xnum=x# xstr=x@, i(id) //通过重命名, 将 x1 和 x2 重新表达为 xnum, 将 xm 和 xf 重新表达为 xstr
. list, sepby(id)
. restore
+---------------------------------+
| id _j xnum xstr |
|---------------------------------|
1. | 1 1 -.4868504 . |
2. | 1 2 -.0109115 . |
3. | 1 f . 1.287317 |
4. | 1 m . .5155788 |
|---------------------------------|
5. | 2 1 -1.476004 . |
6. | 2 2 -.0137603 . |
7. | 2 f . -.587773 |
8. | 2 m . -.1391217 |
+---------------------------------+
. rename (x*) (x*x) // 将 x1 x2 xm xf 批量重命名为 x1x x2x xmx xfx
. preserve
. tolong x#x, i(id) // 将数据转换成长数据格式, x#x 代表 x1x 和 x2x, 该命令等价于 reshape long x@x, i(id)
. list, sepby(id)
. restore
+--------------------------------------------+
| id _j xmx xfx xx |
|--------------------------------------------|
1. | 1 1 .5155788 1.287317 -.4868504 |
2. | 1 2 .5155788 1.287317 -.0109115 |
|--------------------------------------------|
3. | 2 1 -.1391217 -.587773 -1.476004 |
4. | 2 2 -.1391217 -.587773 -.0137603 |
+--------------------------------------------+
. preserve
. // 将数据转换成长数据, 其中 x*x 代表 x1x,x2x, xmx, 和 xfx
. // 该命令等价于 reshape long x@x, i(id) string
. tolong x*x, i(id)
. list, sepby(id)
. restore
+---------------------+
| id _j xx |
|---------------------|
1. | 1 1 -.4868504 |
2. | 1 2 -.0109115 |
3. | 1 f 1.287317 |
4. | 1 m .5155788 |
|---------------------|
5. | 2 1 -1.476004 |
6. | 2 2 -.0137603 |
7. | 2 f -.587773 |
8. | 2 m -.1391217 |
+---------------------+
. preserve
. tolong x@x, i(id) // x@x 代表 xmx 和 xfx
. list, sepby(id)
. restore
+---------------------------------------------+
| id _j x1x x2x xx |
|---------------------------------------------|
1. | 1 f -.4868504 -.0109115 1.287317 |
2. | 1 m -.4868504 -.0109115 .5155788 |
|---------------------------------------------|
3. | 2 f -1.476004 -.0137603 -.587773 |
4. | 2 m -1.476004 -.0137603 -.1391217 |
+---------------------------------------------+
通过上面的简单介绍,我们可能会认为
tolong
命令能做的
reshape long
命令也能做到。实际上,在数据量较少时,二者的差距看不出来,但是当数量特别大时,二者差距就很明显了。为此,我们仍然使用上述简单的宽数据来测试一下二者的运行速度。
sysuse tolong.dta,replace
. timer clear 1
. timer on 1
. reshape long x, i(id) string
. list, clean noobs
. timer off 1
. timer list 1
. global t1 = r(t1)
. disp in y `"reshape 命令用时 $t1 秒"'
. sysuse tolong.dta,replace
. timer clear 2
. timer on 2
. tolong x*,i(id)
. list, clean noobs
. timer off 2
. timer list 2
. global t2= r(t2)
. disp in y `"tolong命令用时 $t2 秒"'
. * 汇总各命令处理数据的用时
. disp in y `"reshape 命令用时 $t1 秒"'
reshape 命令用时 .027 秒
. disp in y `"tolong 命令用时 $t2 秒"'
tolong 命令用时 .001 秒
4. tolong 和 reshape long 对比
首先,当
i(id)
不唯一时也能使用
tolong
命令转换,但
reshape long
不能。因此,为了确定
i(id)
是否唯一,可以在使用
tolong
命令之前,用
list id
命令先检验一下。
其次,当变量名称 j 中同时有数字型和字符型值时,
tolong
命令可以直接使用通配符 * 来代表数字和字符型值,或者单独使用 # 代表数字型,@ 代表字符型。但在
reshape long
中只能使用通配符 @ 来控制数字和字符串索引的位置,并没有单独用来隔离字符串索引的方法。
最后,在默认的情况下,使用
tolong
命令进行转换之后,变量的顺序不是按照
i()
和
j()
变量的顺序排序,而是按照原始
i()
的顺序排序。然后在每个
i()
的组内,再按照新的
j()
的顺序来进行排序。当然,我们也可以直接使用
sort
命令按照
i()
、
j()
的顺序排序,此时就和
reshape long
一样。
5. 相关推文
Note:产生如下推文列表的 Stata 命令为:
lianxh reshape readWind 转换, m
安装最新版
lianxh
命令:
ssc install lianxh, replace
-
-
-
Stata-dofile-转换-PDF-制作讲义方法
-
-
Stata新命令:readWind-快速读入并转换万德数据
-
Stata新命令-tobalance:非平行面板转换为平行面板数据
-
-
Stata:时间序列数据转换-tstransform
-
-
-