【问题标题】:Stata - how to create T variables that have values for each t in panel dataStata - 如何创建具有面板数据中每个 t 值的 T 变量
【发布时间】:2016-10-14 14:50:55
【问题描述】:

对不起,如果我的问题的标题不清楚,但很难在一行中总结出来。我有一个面板数据集(生成它的代码在底部):

. xtset id year
       panel variable:  id (strongly balanced)
        time variable:  year, 1 to 3
                delta:  1 unit

. l, sep(3)

     +-----------------+
     | id   year     x |
     |-----------------|
  1. |  1      1   1.1 |
  2. |  1      2   1.2 |
  3. |  1      3   1.3 |
     |-----------------|
  4. |  2      1   2.1 |
  5. |  2      2   2.2 |
  6. |  2      3   2.3 |
     +-----------------+

我想创建变量x_1x_2x_3,其中x_jyear 中对于每个id 具有x 的值。我可以按如下方式实现(不追求优雅):

. forv k=1/3 {
  2. capture drop tmp
  3. gen tmp = x if year==`k'
  4. by id: egen x_`k' = mean(tmp)
  5. }
(4 missing values generated)
(4 missing values generated)
(4 missing values generated)

. drop tmp

. l, sep(3)

     +-----------------------------------+
     | id   year     x   x_1   x_2   x_3 |
     |-----------------------------------|
  1. |  1      1   1.1   1.1   1.2   1.3 |
  2. |  1      2   1.2   1.1   1.2   1.3 |
  3. |  1      3   1.3   1.1   1.2   1.3 |
     |-----------------------------------|
  4. |  2      1   2.1   2.1   2.2   2.3 |
  5. |  2      2   2.2   2.1   2.2   2.3 |
  6. |  2      3   2.3   2.1   2.2   2.3 |
     +-----------------------------------+

有没有不使用循环的方法?我知道我可以编写一个programado 文件(自动确定变量名),但我想知道是否有一些内置命令适合我的目的。

完整的命令在这里。

clear all
set obs 6
gen id = floor((_n-1)/3)+1
by id, sort: gen year = _n
xtset id year
gen x = id+year/10
l, sep(3)
forv k=1/3 {
    capture drop tmp
    gen tmp = x if year==`k'
    by id: egen x_`k' = mean(tmp)
}
drop tmp
l, sep(3)

【问题讨论】:

  • 感谢您提供清晰、可重复的示例。

标签: stata


【解决方案1】:

循环很好。我能为你做的是缩短你的循环:

clear all
set obs 6
gen id = floor((_n-1)/3)+1
by id, sort: gen year = _n
xtset id year
gen x = id+year/10
l, sep(3)

forv k=1/3 {
    by id: gen x_`k' = x[`k'] 
}

l, sep(3)

其中有一个平衡面板的体面假设。这个循环没有做这样的假设,但你需要循环观察到的年份:

forv year = 1/3 {
    by id: egen X_`year' = total(x / (year == `year'))  
}

另请参阅this discussion,尤其是第 9 节和第 10 节。

您可能还对separate 感兴趣,它避免了显式循环,但只会让您部分到达您想去的地方。

说了这么多,很难相信你需要这些变量。时间序列算子的机制解决了很多问题,而rangestat(SSC)等工具填补了很多空白。

【讨论】:

  • 很棒的提示!谢谢。我对他们很满意。我需要这些变量用于张伯伦的随机效应概率和其他相关程序,例如 Wooldridge (2005, JAE)。不确定我是否可以避免生成它们。
  • 如果 year 是 1990, 1995, 2000, ... 则只有使用 egentotal 的循环无需修改即可工作。如果这是正确的,@Nick Cox,您是否会编辑您的答案以为我和其他人添加评论,尽管您的“平衡面板”评论暗示了这一点?谢谢。
【解决方案2】:

一个较晚的条目,但如果您愿意,可以使用 reshapemerge 来避免循环:

clear *
input float(id year x)
1 1 1.1
1 2 1.2
1 3 1.3
2 1 2.1
2 2 2.2
2 3 2.3
end

tempfile master
save `master'

reshape wide x, i(id) j(year)

tempfile using
save `using'

use `master', clear
merge m:1 id using `using', nogen

【讨论】:

  • 谢谢。一个聪明的解决方案,又好又短。它处理不平衡的面板数据和多个变量。需要临时文件让我有些烦恼,但除此之外,我也对您的建议感到满意。当 T 很大时,它可能会很快。
【解决方案3】:

这个“答案”,因为它作为评论太长而发布,包含遵循尼克考克斯答案的实践结果。所有功劳归他所有。

方法一:使用egentotal, missing

levelsof year, local(yearlevels)
foreach v of varlist x {
    foreach year of local yearlevels {
        by id: egen `v'_`year' = total(`v' / (year==`year')), missing
    }
}

missing 选项处理不平衡的面板。

方法2:使用separate,然后复制值。

foreach v of varlist x {
    separate `v', by(year) gen(`v'_)
    local newvars = r(varlist)
    foreach w of local newvars {
        by id: egen f_`w' = total(`w'), missing
    }
    drop `newvars'
}

这也处理不平衡的面板,但是新的变量名称是f_x_1等。第一种方法需要year的级别,而第二种需要创建一组中间变量。我个人稍微喜欢第一个。如果方法二能缩短就好了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 2017-11-12
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多