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

发布时间:2022-06-21 阅读 677

Stata连享会   主页 || 视频 || 推文 || 知乎 || Bilibili 站

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

New! lianxh 命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc, ihelp, rdbalance, gitee, installpkg

课程详情 https://gitee.com/lianxh/Course

课程主页 https://gitee.com/lianxh/Course

⛳ Stata 系列推文:

PDF下载 - 推文合集

作者:李坤 (华南师范大学)
邮箱kunli1001@163.com


目录


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 代表转换后的新变量。新变量名必须是原来变量名中的一部分,例如原变量名分别为 one1one2,则 newvar 可以设定为 one

stubname 代表需要转换的变量,可以是单个也可以是多个。如果为多个,则需要依次列出转换变量。其中,

  • stubname#:如要转换的变量名称为 two1two2two3,可直接使用 two# 代替;
  • stubname@:如要转换的变量名称为 threeathreebthreec,则可直接使用 three@ 代替;
  • stubname*:与直接使用 stubname 的含义一样。

除此之外,

  • i(varlist) 代表 ID 变量,需要是唯一的。如果省略此选项,则 i 变量将被命名为 _i,且顺序为观察编号;
  • j(newvar)stubname 子集的变量名。即代表变量 fourafourbfourc 中的 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

相关课程

免费公开课

最新课程-直播课

专题 嘉宾 直播/回看视频
最新专题 文本分析、机器学习、效率专题、生存分析等
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]
  • Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。

课程主页

课程主页

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 连享会-主页知乎专栏,700+ 推文,实证分析不再抓狂。直播间 有很多视频课程,可以随时观看。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会-常见问题解答:
https://gitee.com/lianxh/Course/wikis

New! lianxhsongbl 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh