专栏名称: 连享会
连玉君老师团队分享,主页:lianxh.cn。白话计量,代码实操;学术路上,与君同行。
目录
相关文章推荐
邳州银杏甲天下  ·  事关2027年高考,省教育厅最新公告 ·  昨天  
单向街书店  ·  【单向历】2 月 21 日,宜静止 ·  3 天前  
新京报书评周刊  ·  几乎不识字的她,完成了一部关于自己的人生叙事 ·  5 天前  
教育之江  ·  图说 | ... ·  3 天前  
教育之江  ·  图说 | ... ·  3 天前  
安徽省教育厅官微  ·  考试报名:3月3日至7日 ·  3 天前  
51好读  ›  专栏  ›  连享会

Stata:宽数据到长数据的转换-tolong

连享会  · 公众号  ·  · 2025-01-06 22:00

正文

👇 连享会 · 推文导航 | www.lianxh.cn

🍓 课程推荐: 连享会:2025 寒假班
嘉宾:连玉君(初级|高级);杨海生(前沿)
时间:2025 年 1 月 13-24 日
咨询:王老师 18903405450(微信)



作者 :李坤 (华南师范大学)
邮箱 [email protected]

温馨提示: 文中链接在微信中无法生效。请点击底部 「阅读原文」 。或直接长按/扫描如下二维码,直达原文:


目录

  • 1. 引言

  • 2. 命令简介

  • 3. 具体案例

  • 4. tolong 和 reshape long 对比

  • 5. 相关推文



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入门
    • Stata:快速转换工作路径
    • Stata-dofile-转换-PDF-制作讲义方法
  • 专题: Stata命令
    • Stata新命令:readWind-快速读入并转换万德数据
    • Stata新命令-tobalance:非平行面板转换为平行面板数据
  • 专题: 数据处理
    • Stata:时间序列数据转换-tstransform
    • Stata数据处理:一月有几周?月度和周数据转换
    • Stata 日期格式转换
    • reshape命令一文读懂!(下)






请到「今天看啥」查看全文