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

时间:2014-02-24 19:07:11

标签: stata

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

目前,我用来完成此操作的代码如下(为了清晰起见而编辑

xtset weocountrycode year
sort weocountrycode year

local win_len = 5 // Defining rolling window length.

quietly: rolling sd_x=r(sd) mean_x=r(mean), window(`win_len') saving(stats_x, replace): sum x 
use stats_x, clear
rename end year
save, replace
use all_data_PROCESSED_FINAL.dta, clear
quietly: merge 1:1 (weocountrycode year) using stats_x  
replace sd_x = . if `x'[_n-`win_len'+1] == . | weocountrycode[_n-`win_len'+1] !=  weocountrycode[_n] // This and next line are for deleting values that rolling calculates when I actually want missing values. 
replace mean_`x' = . if `x'[_n-`win_len'+1] == . | weocountrycode[_n-`win_len'+1] != weocountrycode[_n]
gen z_`x' = (`x' - mean_`x'[_n-1])/sd_`x'[_n-1] // calculate z-score

更新

我对滚动的困难是当滚动设置为使用窗口长度5滚动平均值时,它会自动执行窗口长度1,2,3,4表示第一,第二,第三和第四个条目(当有没有5个前面的条目可用于平均值)。实际上,它通常会这样做 - 如果第一个非缺失值在条目5上,它将在条目5上进行长度1滚动平均,在条目6上进行长度2滚动平均,.....然后最终开始在条目9上做5个移动平均线。我的问题是我不想要这个,所以我想避免执行这些计算。到目前为止,我只能弄清楚如何在完成后删除它们,这既低效又麻烦。

我尝试在-rolling-语句中添加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)if子句如何在-rolling的上下文中起作用。

这有帮助吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

我不确定我完全理解,但我会根据我认为你的问题,并根据@NickCox的评论来回答。

你说:

  

...当滚动设置为使用窗口长度5滚动平均值...   如果第一个非缺失值是   在第5项中,它将在第5项(长度2)上进行长度1滚动平均   第6项滚动平均值,......

这是预期的。 help rolling声明:

  

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

它实际上并没有做“长度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)

注意我使用stepsize选项使事情更容易理解。由于日期变量是四分之一,因此我设置了windowsize(4)stepsize(4),因此rolling只是按年计算平均值。我希望这很容易看到。

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

  • 示例2 另一方面,对您来说应该更有趣。我们已经说过重要的是日历期,所以平均值是计算全年(四个季度),即使它包含缺失。有三个缺失和一个非缺失。 summarize计算全年的平均值,但summarize忽略了缺失,因此它只输出非缺失的平均值,在这种情况下只是一个值。

  • 示例3 在一年中的所有四个季度都有错误。因此,summarize输出.(缺失)。

根据我的理解,您的问题是当您遇到类似示例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),也由summarize计算)与窗口大小不同,则将其替换为缺失。