Stata数据处理:数据框使用教程

发布时间:2022-06-06 阅读 847

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下载 - 推文合集

作者:陈卓然 (中山大学)
邮箱chenzhr25@mail2.sysu.edu.cn


目录


1. 数据框简介

在 Stata16 以后,Stata 开始允许使用数据框。这意味着我们可以将多个数据集存储在 Stata 内存中,并对不同的数据集同时进行处理。对于经常处理单一大型数据的人来说,他们再也不用总是 preserve restore 了,也不用再将无数个数据集合并到一起,这大大提高了数据处理的效率。为了实现上述目的,我们需要学会如何使用数据框,以及如何在不同的数据框之间建立联系。

在正式开始介绍之前,我们先简单了解一下数据框。打开 Stata16 或者更高级的版本,输入以下命令,我们发现当前的数据框是 default。这是因为在没有指定数据框前,Stata 加载的数据都会存储在名为 default 的数据框中。当然我们也可以通过命令 frames rename,来更改数据框的名称。需要注意的是,命令 framesframe 可以相互替换。

. sysuse auto, clear
. frames
  (current frame is default)

. frames rename default carUS
. frames
  (current frame is carUS)

2. 数据集子集

如果要对 auto.dta 数据集中的几个变量进行分析,我们可以将这几个变量放入到一个新的数据框中。例如,我们需要将变量 makepricempg 放入到数据框 mysubset 中,我们可以运行以下代码:

. frames put make price mpg, into (mysubset)
. frames dir
  carUS     74 x 12; 1978 automobile data
* mysubset  74 x 3; 1978 automobile data
Note: Frames marked with * contain unsaved data.

. frames
  (current frame is carUS)

可以看出,我们有两个数据框 carsUS 和 mysubset,当前数据框是 carUS。如果想从数据框 carUS 转换到 mysubset,我们可以使用如下命令:

. frame change mysubset
. frames
  (current frame is mysubset)

如果想要对数据框 mysubset 进行分析,但不需要转换到该数据框中,我们可以运行如下命令:

. frame mysubset: des2

variable name   type    format    value label   variable label
-----------------------------------------------------------------------
make            str18   %-18s                   Make and model
price           int     %8.0gc                  Price
mpg             int     %8.0g                   Mileage (mpg)

. frame mysubset: summ price

    Variable |        Obs        Mean    Std. dev.       Min        Max
-------------+---------------------------------------------------------
       price |         74    6165.257    2949.496       3291      15906

当然,我们也可以采用循环的方式对全部变量逐个进行描述性分析,具体命令如下:

. frame mysubset {
.     foreach x of varlist _all {
  2.      summ `x'
  3.  }
. }

    Variable |        Obs        Mean    Std. dev.       Min        Max
-------------+---------------------------------------------------------
        make |          0
        
    Variable |        Obs        Mean    Std. dev.       Min        Max
-------------+---------------------------------------------------------
       price |         74    6165.257    2949.496       3291      15906

    Variable |        Obs        Mean    Std. dev.       Min        Max
-------------+---------------------------------------------------------
         mpg |         74     21.2973    5.785503         12         41

这个简单的小例子告诉我们,在对不同数据框进行操作时,基本语法格式为:

frame <framename> {
    some stata commands
}

3. 数据框使用

数据框绝不仅仅是用来提取数据子集的,我们也可以用来拷贝原始数据:

. frames copy carUS mycarUS
. frame dir
  carUS     74 x 12; 1978 automobile data
  mycarUS   74 x 12; 1978 automobile data
* mysubset  74 x 3; 1978 automobile data

可以生成一个空数据框,然后加载一些新的数据到这个数据框:

. frames create otherdata 
. frames otherdata: sysuse census
(1980 Census data by state)

. frame dir
  carUS      74 x 12; 1978 automobile data
  mycarUS    74 x 12; 1978 automobile data
* mysubset   74 x 3; 1978 automobile data
  otherdata  50 x 13; 1980 Census data by state

可以清空数据框:

. * 这两个命令等价
. clear frames 
. frames reset  

. frame dir
  default  0 x 0

如果只想清除某一个数据框,只需要输入:

. frames drop mycarUS

4. 将统计结果存储在数据框中

如果将 carUS 中每一个变量的均值和标准差存储在另外一个数据框中,并挑选出数值变量,我们需要进行如下操作:首先创建一个空数据框,并产生相关变量。

. cap frame drop sumstats
. frames create sumstats str15(variable) mean sd

然后,我们提取数值型变量,并将其均值和标准差存储在数据框 sumstats 中。

. * pick variables which are numeric 
. ds, has(type numeric)
. local mylist `r(varlist)'

. * loop and store information
. foreach x of local mylist { 
  2.    qui summ `x'
  3.    frame post sumstats ("`x'") (r(mean)) (r(sd))
  4. }

这里使用到命令 frame post,它的语法格式为:

frames post <framename> (var1) (var2) (var3)

在使用 frames post 的时,有两点注意事项:

  • frame post 中添加的变量个数一定不能超过数据框中变量个数;
  • frame post 本质上是 append 命令。这意味着在循环时,如果不及时清除数据框,那么 frame post 会在同一数据框中添加数据,而不是覆盖原有数据。

5. 将回归结果存储在数据框中

首先,我们导入数据,并估计如下方程:

. frames reset
. lxhuse nlswork, clear
. xtset idcode year
. g age2 = age^2
. g black = (race == 2)
. xtreg ln_w grade age age2 tenure black south

接着,我们创建一个新的数据框 results,并生成相关变量。

. cap frame drop results
. frame create results str15(model variable) mean se

最后,我们将回归结果存储到数据框 results 中。

. * Random-effects model
. local varlist "grade age age2 tenure black south"
. xtreg ln_w `varlist', re
. foreach x in `varlist' _cons {
  1.     frame post results ("re") ("`x'") (_b[`x']) (_se[`x'])
  2. }

. * Fixed-effects model
. xtreg ln_w `varlist', fe 
. foreach x in `varlist' _cons {
  2.    frame post results ("fe") ("`x'") (_b[`x']) (_se[`x'])
  3. }

. * Random-effects model using MLE
. xtreg ln_w `varlist', mle 
. foreach x in `varlist' _cons {
  2.     frame post results ("mle") ("`x'") (_b[`x']) (_se[`x'])
  3. }

. frame results: list

     +-----------------------------------------+
     | model   variable        mean         se |
     |-----------------------------------------|
  1. |    re      grade    .0733589    .001862 |
  2. |    re        age    .0517477   .0026624 |
  3. |    re       age2   -.0006903   .0000441 |
  4. |    re     tenure     .025796   .0007288 |
  5. |    re      black   -.0354088    .010513 |
     |-----------------------------------------|
  6. |    re      south    -.106246   .0075266 |
  7. |    re      _cons   -.1763739   .0443129 |
  8. |    fe      grade           0          0 |
  9. |    fe        age     .052113   .0027815 |
 10. |    fe       age2   -.0006673   .0000461 |
     |-----------------------------------------|
 11. |    fe     tenure    .0215835   .0007989 |
 12. |    fe      black           0          0 |
 13. |    fe      south   -.0697603   .0111167 |
 14. |    fe      _cons    .7170634   .0408609 |
 15. |   mle      grade    .0733416   .0018278 |
     |-----------------------------------------|
 16. |   mle        age    .0517524   .0026673 |
 17. |   mle       age2   -.0006914   .0000442 |
 18. |   mle     tenure    .0259506   .0007329 |
 19. |   mle      black   -.0354719   .0103123 |
 20. |   mle      south   -.1070148   .0074688 |
     |-----------------------------------------|
 21. |   mle      _cons   -.1751722   .0441207 |
     +-----------------------------------------+

如果我们需要提取出系数、标准差、置信区间的上下界,并放在数据框 indextest 中,我们可以借助回归后矩阵 r(table) 实现。

. xtreg ln_w grade age age2 tenure black south, re
. mat li r(table)

r(table)[9,7]
             grade         age        age2      tenure       black       south       _cons
     b    .0733589   .05174773  -.00069031   .02579596  -.03540883  -.10624599  -.17637391
    se   .00186197   .00266236    .0000441   .00072876   .01051301   .00752658   .04431291
     z   39.398606   19.436806  -15.653408   35.397072  -3.3680966  -14.116102  -3.9801921
pvalue           0   3.769e-84   3.149e-55   1.89e-274   .00075689   3.023e-45   .00006886
    ll   .06970951   .04652961  -.00077675   .02436762  -.05601395  -.12099782  -.26322562
    ul   .07700829   .05696586  -.00060388    .0272243  -.01480371  -.09149416   -.0895222
    df           .           .           .           .           .           .           .
  crit    1.959964    1.959964    1.959964    1.959964    1.959964    1.959964    1.959964
 eform           0           0           0           0           0           0           0

. cap frame drop indextest
. frame create indextest str20(variable) mean sd ll ul
. local varlist "grade age age2 tenure black south"
. xtreg ln_w `varlist', re
. local i = 1
. foreach x in `varlist' _cons {
  2. frame post indextest ("`x'") (r(table)[1,`i']) (r(table)[2,`i']) (r(table)[5,`i']) (r(table)[6,`i'])
  3.     local i = `i' + 1 
  4. }
. frame change indextest
. list

     +---------------------------------------------------------+
     | variable        mean         sd          ll          ul |
     |---------------------------------------------------------|
  1. |    grade    .0733589    .001862    .0697095    .0770083 |
  2. |      age    .0517477   .0026624    .0465296    .0569659 |
  3. |     age2   -.0006903   .0000441   -.0007767   -.0006039 |
  4. |   tenure     .025796   .0007288    .0243676    .0272243 |
  5. |    black   -.0354088    .010513    -.056014   -.0148037 |
     |---------------------------------------------------------|
  6. |    south    -.106246   .0075266   -.1209978   -.0914942 |
  7. |    _cons   -.1763739   .0443129   -.2632256   -.0895222 |
     +---------------------------------------------------------+

6. 数据框之间的连接

数据框的连接允许我们不用将全部数据合并为一个大文件后再操作,不过 Stata 中数据框的连接暂时还不支持 1:m 型。接下来,我们将以 1:1 型的连接为例进行介绍。我们首先调入 atuo.dta 数据集,生成变量 id。然后将变量 id 存储到数据框 otherdata 中,并生成两个新变量。

. frames reset
. sysuse auto, clear
. gen id = _n
. order id
. frames put id, into (otherdata)
. frames otherdata: gen var1 = rnormal()
. frames otherdata: gen var2 = runiform()
. frame dir
* default    74 x 13; 1978 automobile data
* otherdata  74 x 3; 1978 automobile data

现在我们要将 default 和 otherdata 两个数据框按照 id 连接起来,可以使用如下命令:

. frlink 1:1 id, frame(otherdata)
  (all observations in frame default matched)
. findname
id            price         rep78         trunk         length        displacement  foreign
make          mpg           headroom      weight        turn          gear_ratio    otherdata

可以发现,我们新生成了一个变量 otherdata,这是 Stata 标识数据框连接的一个变量 (千万不要对这个变量做任何操作)。我们可以使用 frlink describe otherdata 的命令来获得连接的一些基本信息,例如何时创建,如何创建等。我们也可以定义连接的变量名,具体代码如下:

. frlink 1:1 id, frame(otherdata) generate(_link_otherdata)

尽管看上去 frlinkmerge 很像,但是 frlink 还是有很大的优势的。例如 frlink 可以允许使用不同的标识变量名进行连接。具体地,一份数据集中标识变量为 id,另一份数据集中的标识变量为 carid,我们可以通过命令语句 frlink 1:1 id, frame(frame1 carid) 完成合并。

需要注意的是,数据框的连接是单方向的,即数据框 1 连接到数据框 2 并不意味着数据框 2 也连接到数据框 1。此外数据框的连接也不具有传递性,即数据框 1 连接到数据框 2,数据框 2 连接到数据框 3,这并不意味数据框 1 自动连接到数据框 3。

7. 玩转 Links

数据框之间的连接建立之后,我们可以使用 frget 的命令从另一个数据框中获取数据并操作。几个比较典型的命令有:

. * copy the variables as they are
. frget var1 var2, from(_link_otherdata)

. * copy and prefix the variables
. frget var1 var2, from(_link_otherdata) prefix(copy_)

. * generate a new variable
. frget newvar = var1, from(_link_otherdata)

我们也可以通过 frval 实现在一部分命令中交互式使用另一个数据框的数据。

. g newvar2 = price/ frval(_link_otherdata, var1)
. regress price mpg if frval(_link_otherdata, var1) < 0.5

不过,frval 不能直接用于回归当中,例如 reg price frvar(_link_otherdata, var1)

8. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh frame 数据处理, 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