在Stata中生成面板数据的滚动z分数

在Stata中生成面板数据的滚动z分数,stata,Stata,我有一个不平衡的面板数据集(国家和年份)。为了简单起见,假设我有一个变量,x,我正在测量。面板数据首先按国家(3位数字国家代码)排序,然后按年份排序。我想编写一个.do文件,生成一个新变量z_x,其中包含变量x的标准值。应通过从之前(不包括)m个时间段中减去平均值,然后除以这些相同时间段的标准偏差来标准化变量。如果不可能,则返回缺少的值 目前,我用于实现这一点的代码如下(为了清晰起见,现在进行编辑) 更新: 我与滚动的斗争是,当滚动设置为使用窗口长度5滚动平均值时,它会自动对第一、第二、第三和第

我有一个不平衡的面板数据集(国家和年份)。为了简单起见,假设我有一个变量,x,我正在测量。面板数据首先按国家(3位数字国家代码)排序,然后按年份排序。我想编写一个.do文件,生成一个新变量z_x,其中包含变量x的标准值。应通过从之前(不包括)m个时间段中减去平均值,然后除以这些相同时间段的标准偏差来标准化变量。如果不可能,则返回缺少的值

目前,我用于实现这一点的代码如下(为了清晰起见,现在进行编辑

更新:

我与滚动的斗争是,当滚动设置为使用窗口长度5滚动平均值时,它会自动对第一、第二、第三和第四个条目执行窗口长度1、2、3、4平均值(当之前没有5个条目可用于平均值)。事实上,它通常是这样做的——如果第一个非缺失值在条目5上,它将在条目5上进行长度1滚动平均,在条目6上进行长度2滚动平均。。。。。最后在第9条开始做长度5的移动平均。我的问题是我不想这样,所以我希望避免执行这些计算。到目前为止,我只知道如何在它们完成后删除它们,这既低效又麻烦

我尝试在-rolling-statement中添加一个if子句:

quietly: rolling sd_x=r(sd) mean_x=r(mean) if x[_n-`win_len'+1] != . & weocountrycode[_n-`win_len'+1] != weocountrycode[_n], window(`win_len') saving(stats_x, replace): sum x
但它并没有解决问题,而且输出在某种意义上是“奇怪的”

1) 如果“win_len”等于(比如)10,则结果z_x变量中缺少15个值,而不是9。 2) 尽管z_x中有“额外”缺失值,但观测值仍然以窗长1表示,然后是窗长2表示,等等开始,这对我来说毫无意义

这让我相信我根本不明白1)滚动在做什么,2)如果子句在滚动上下文中是如何工作的

这有用吗


谢谢

我不确定自己是否完全理解,但我会根据我认为您的问题所在以及@NickCox的评论来回答

你说:

。。。当滚动设置为使用窗口长度5滚动平均值时。。。 如果第一个非缺失值为 在条目5上,它将在条目5(长度2)上进行长度1的滚动平均 分录6的滚动平均值

这是意料之中的<代码>帮助滚动说明:

窗口大小指的是日历期间,而不是 观察。如果有 如果缺少数据(例如,由于周末),则命令使用的实际观察数可能少于 窗口(#)

它实际上并没有做一个“长度1滚动平均值”,但我稍后再讨论。 下面是一些示例,以了解
rolling
的作用:

clear all
set more off

*-------------------------- example data -----------------------------

set obs 92

gen dat = _n - 1
format dat %tq

egen seq = fill(1 1 1 1 2 2 2 2)

tsset dat

tempfile main
save "`main'"

list in 1/12, separator(4)


*------------------- Example 1. None missing ------------------------

rolling mean=r(mean), window(4) stepsize(4) clear: summarize seq, detail
list in 1/12, separator(0)


*------- Example 2. All but one value, missing in first window ------

use "`main'", clear
replace seq = . in 1/3
list in 1/8

rolling mean=r(mean), window(4) stepsize(4) clear: summarize seq, detail
list in 1/12, separator(0)


*------------- Example 3. All missing in first window --------------

use "`main'", clear
replace seq = . in 1/4
list in 1/8

rolling mean=r(mean), window(4) stepsize(4) clear: summarize seq, detail
list in 1/12, separator(0)
注意:我使用
步长
选项使事情更容易理解。因为日期变量是以季度为单位的,所以我设置了
windowsize(4)
stepsize(4)
所以
rolling
只是按年度计算平均值。我希望这很容易看出来

  • 示例1按预期执行。没问题

  • 另一方面,例2对您来说应该更有趣。我们已经说过,重要的是日历周期,因此计算全年(四个季度)的平均值,即使它包含遗漏。有三处失踪,一处未失踪
    Summary
    计算全年的平均值,但
    Summary
    忽略缺失,因此它只输出未缺失的平均值,在本例中,这只是一个值

  • 例3在一年的所有四个季度都有遗漏。因此,
    汇总
    输出
    (缺失)

据我所知,您的问题是,当您面临示例2这样的情况时,您希望输出丢失。这就是我认为尼克·考克斯的建议的用武之地。您可以尝试以下方法:

rolling mean=r(mean) N=r(N), window(4) stepsize(4) clear: summarize seq, detail
replace mean = . if N != 4
list in 1/12, separator(0)

这意味着:如果窗口的不丢失次数(
r(N)
,也由
summary
)计算)与窗口大小不一样,那么用missing替换它。

事实上,这里的细节太多了,我不喜欢。你能在一句话中分离出什么
rolling
没有做你想做的事,或者做了你不想做的事吗?以上更新。用一句话来说:rolling试着做一个平均值,但它不能真正做到我要求的;我宁愿它在数据不可用时只返回一个缺少的值,而只是尝试使用它可用的值。如果您将
r(N)
的结果保存在
summary
之后,您可以
替换
基于不完整窗口的其他结果。因此,没有办法让滚动不计算这些值?这会浪费很多时间,而且会打印大量的e。您可以使用
悄悄地
作为
滚动
的前缀,或者使用
nodots
选项来抑制显示。你能把额外的计算时间和你花在修复你不喜欢的东西上的时间相比较吗?你很好地理解了我的观点。顺便说一句,如果您只想从
汇总
中获得计数和平均值,那么您不需要
详细信息
选项;相反,您可以仅应用
meansonly
。OP也需要SD,所以这与这里的主要问题无关。太好了,谢谢你的回答。上述方法仍在计算所有值,稍后将替换为缺少的值。有人知道有没有办法避免这种情况吗?这看起来很浪费,而且Stata在控制台上打印的红色字母“e”很麻烦。不客气。就像我说的,
summary
只是忽略了遗漏。这就是它的工作方式。这比在存在非缺失值时输出缺失值更有意义。使用
rolling mean=r(mean) N=r(N), window(4) stepsize(4) clear: summarize seq, detail
replace mean = . if N != 4
list in 1/12, separator(0)