滚动计算:rangerun和rangestat命令简介

连享会 · 文本分析-爬虫-机器学习


目录

  • ⏩ 连享会 · 文本分析-爬虫-机器学习

  • 1. 简介

  • 2. rangerun 命令

    • 2.1 语法格式

    • 2.2 与 `rangestat` 对比

    • 2.3 与 `rolling` 对比

    • 2.4 与 `statsby` 对比

    • 2.5 与循环观察值对比

    • 2.6 滚动窗口上的加权回归

  • 3. rangestat 命令

    • 3.1 语法格式

    • 3.2 设置间隔

    • 3.3 控制样本

    • 3.4 使用内置函数

    • 3.5 与 `tsegen` 对比

  • 4. 参考文献

  • 5. 相关推文

    • ⏩ 连享会 · 文本分析-爬虫-机器学习


1. 简介

rangeruanrangestat 都可以进行滚动计算。

其中,rangestat 可以基于退化窗口、滚动窗口、递归窗口、反向递归窗口或特定窗口进行计算,可以完美使用 Stata 中的内置函数。为了提升运行速度,还可以直接使用自定义的 Mata 函数。在大型数据面前,比 tsegen具有更高的执行效率。

rangerun 命令可以完成与 rangestat 相同的功能,但 rangestat 只能使用内置函数,或者编写的 Mata 函数。rangerun 执行速度比 rangestat 稍慢,但它更灵活,因为 rangerun 可以使用自定义函数。对于大型数据,rangerunrollingstatsby和循环,具有明显的效率优势。

接下来,本文将具体介绍上述命令的应用。

2. rangerun 命令

2.1 语法格式

*命令安装ssc install rangerun, replace
*语法格式rangerun program_name [if] [in], interval(keyvar low high) [ options ]
  • program_name:定义的程序名;
  • interval(keyvar low high):根据关键变量取值范围,限定观察样本,例如 interval(yearmonth -11 0),则为过去 12 个月;
  • by(varlist):根据变量分组;
  • use(varlist):程序 program_name 处理变量集合;
  • sprefix(string):变量名前缀,用于创建保存当前观测值的标量;
  • verbose:运行 program_name 程序的过程结果输出到屏幕。

2.2 与 rangestat 对比

rangerunrangestat 非常相似,不过在使用 rangestat 时,只能使用内置函数,或者创建的 Mata 函数。

以公司数为 100,期限为 360 个月,且存在缺失值的样本数据为例,计算滚动窗口为 12 个月的 invest 变量统计数据。具体代码如下:

*create data for 100 companies over 360 monthsclear allset seed 31231set obs 100

gen long company = _nexpand 360bysort company: gen mdate = ym(1987,1) + _nformat %tm mdate

gen invest = runiform() if runiform() < .95drop if runiform() < .05

*rangestattimer on 1rangestat (count) invest (mean) invest (sd) invest, ///    interval(mdate -11 0) by(company)timer off 1

*rangerunprogram myprog  sum invest  gen rrun_n = r(N)  gen double rrun_mean = r(mean)  gen double rrun_sd = r(sd)endtimer on 2  // timer 用以程序计时,详见 help timerrangerun myprog, interval(mdate -11 0) use(invest) by(company)timer off 2timer list

* confirm that results are the same using both methodsassert rrun_n == invest_countassert rrun_mean == invest_meanassert rrun_sd == invest_sd
. timer list   1:      0.58 /        1 =       0.5770   2:      2.33 /        1 =       2.3290

. * confirm that results are the same using both methods. assert rrun_n == invest_count. assert rrun_mean == invest_mean. assert rrun_sd == invest_sd

可以看出,rangerun 执行速度比 rangestat 慢一点,但它由于允许用户自定义程序,因而也更加灵活。

2.3 与 rolling 对比

*rollingclear allwebuse lutkepohl2, clear //数据地址:https://gitee.com/arlionn/data/blob/master/data01/lutkepohl2.dtatsset qtrtimer on 1rolling ratio1=(r(mean)/r(p50)), window(10): summarize inc, detailtimer off 1

*rangerunprogram myprog  if _N < 10 exit  summarize inc, detail  gen ratio2 = r(mean)/r(p50)endwebuse lutkepohl2, cleartimer on 2rangerun myprog, interval(qtr -9 0) use(inc)timer off 2timer list
. timer list   1:      0.15 /        1 =       0.1480   2:      0.02 /        1 =       0.0230

可以看出,rangerun 执行速度比 rolling 快,且随着数据量的增加,rolling 的执行速度呈指数增长。

2.4 与 statsby 对比

*statsbyclear allsysuse auto.dta, cleartimer on 1statsby mean=r(mean) sd=r(sd) size=r(N), by(rep78):  summarize mpgtimer off 1list size mean sd if rep78 == 2

*rangerunprogram myprog  if mi(rep78) exit  sum mpg  gen size = r(N)  gen mean = r(mean)  gen sd = r(sd)end

sysuse auto.dta, cleartimer on 2rangerun myprog, interval(rep78 0 0) by(rep78)timer off 2timer list
. timer list   1:      0.05 /        1 =       0.0520   2:      0.03 /        1 =       0.0250

需要注意的是,要复制 statsby 功能,需要指定一个 by(rep78) 选项和一个时间间隔,且该间隔必须包含组别中的所有观察值,例如 interval(rep78 0 0),当然也可以是其他形式。同时可以看出,rangerunstatsby 速度快。

2.5 与循环观察值对比

对每个公司进行滚动窗口为 7 年,且至少需要 4 年数据的回归,并保存常数项。

*循环clear allwebuse grunfeld.dta, clear //数据地址:https://gitee.com/arlionn/data/blob/master/data01/grunfeld.dtalocal nobs = _Ngen alpha = .timer on 1quietly forvalues i = 1/`nobs' {  capture regress invest kstock if company == company[`i'] & ///    inrange(year, year[`i']-6, year[`i'])  if _rc == 0 & e(N) >= 4 replace alpha = _b[_cons] in `i'}timer off 1

*rangerunprogram myprog  if _N < 4 exit  regress invest kstock  gen alpha_rr = _b[_cons]endtimer on 2 rangerun myprog, interval(year -6 0) by(company)timer off 2timer list

assert alpha == alpha_rr
. timer list   1:      2.07 /        1 =       2.0730   2:      1.43 /        1 =       1.4330

. assert alpha == alpha_rr

2.6 滚动窗口上的加权回归

进行滚动窗口为 5 年的滚动回归,且观测权重从 1 增加至 5。具体代码如下:

clear allwebuse grunfeld.dta, clear //数据地址:https://gitee.com/arlionn/data/blob/master/data01/grunfeld.dta

* define the program and include all desired commandsprogram my_rw_reg  if _N < 5 exit  gen long myweight = _n  regress invest mvalue [aw=myweight]  gen b_mvalue = _b[mvalue]  gen b_cons = _b[_cons]  drop myweightend

rangerun my_rw_reg, interval(year -4 0) by(company) use(invest mvalue)

3. rangestat 命令

3.1 语法格式

*命令安装ssc install rangestat, replace
*语法格式rangestat slist [if] [in] , interval(keyvar low high) [ options ]
  • interval(keyvar low high):根据关键变量取值范围,限定观察样本;
  • by(varlist):分组;
  • excludeself:将变量当前值设置为缺失;
  • casewise:逐个删除可变组别内的观察值;
  • describe:显示变量名称等信息;
  • local(name):定义一个包含创建变量名称的宏。

在大多数情况下,可以使用 keyvar 变量的当前观测值定义区间界限。也可以通过使用 #(Stata 术语中的数字)指定每个边界来实现。 被添加到 keyvar 中设置界限时,与rangerun 设定一样。rangestat 使用封闭的间隔,这意味着将包含与边界匹配的值。

3.2 设置间隔

退化间隔。最简单的情况是使用具有相同 keyvar 值的观测值来计算统计数据。在这里,我们将 lowhigh 的值同时设为 0。

sysuse auto, clearrangestat (min) price mpg (mean) price mpg, interval(rep78 0 0)

* redo using egen functionssort rep78 makeby rep78: egen min_price  = min(price)by rep78: egen min_mpg    = min(mpg)by rep78: egen mean_price = mean(price)by rep78: egen mean_mpg   = mean(mpg)

list rep78 *price* in 1/4, sepby(rep78)

滚动窗口间隔。使用 rangestat,可以轻松地在滚动窗口上执行计算。下面的示例使用 5 年的窗口,并包含当前的观察结果。

webuse grunfeld.dta, clear

* include some missing values and omit some random observationsset seed 1234replace invest = . if uniform() < .1drop if uniform() < .1

rangestat (mean) invest (sd) invest (count) invest, ///          interval(year -4 0) by(company)

递归窗口间隔。类似于依次累加。下面的示例使用系统缺失值指定 low,使用 0 指定 high。当系统缺失值用于下限时,rangestat假定所有观察值都使用最大的负数。

webuse grunfeld.dta, clearrangestat (sum) invest mvalue kstock, interval(year . 0) by(company)

* the above is the same as performing a running sumby company (year): gen double rs_invest = sum(invest)by company (year): gen double rs_mvalue = sum(mvalue)by company (year): gen double rs_kstock = sum(kstock)

反向递归窗口。类似于依次递减。以下示例使用 0 指定 low,使用系统缺失值指定 high。在 Stata 中,系统缺失值大于任何非缺失值。

webuse grunfeld.dta, clear

rangestat (sum) invest, interval(year 0 .) by(company)

* this above is the same as removing a running sum from the overall totalby company (year): egen double invest_total = total(invest)by company (year): gen double rsum = sum(invest)by company (year): gen double match = invest_total - rsum + invest

特定观察间隔。lowhigh 还可以根据变量设定。以下示例查找 price 相近汽车的平均维修记录。

sysuse auto.dta, clear

gen low = .9 * pricegen high = 1.1 * pricerangestat (mean) rep78, interval(price low high)

* spot check results for observation 15list make price rep78 low high rep78_mean in 15

*类似于以下功能sum rep78 if inrange(price, low[15], high[15])

3.3 控制样本

rangestat 支持 ifin 限定符。

sysuse auto, clearrangestat (mean) price (count) price if foreign, interval(rep78 0 0)

仅使用某些数据的计算结果代替所有观测结果。例如,用外国车平均价格替代外国车和国产车的平均价格。

sysuse auto.dta, clearclonevar price_foreign = price if foreignrangestat (mean) price_foreign (count) price_foreign, interval(rep78 0 0)

*类似于bys rep78: egen price_foreign_mean1 = mean(price_foreign) if rep != .

再比如,以 rep78 每组第一行价格代替该组平均价格。

sysuse auto, clear

* tag the first observation per level of rep78bysort rep78 (make): gen first = _n == 1

* create bounds for the first observation, use [1,0] for the restby rep78: gen low  = cond(first, rep78, 1)by rep78: gen high = cond(first, rep78, 0)

rangestat (mean) price (count) price, interval(rep78 low high)

3.4 使用内置函数

相似年龄人群的平均工资。计算年龄相差 1 岁,且同种族、同行业,但不包括自身的的人群平均工资。

sysuse nlsw88.dta, clear

* calculate expected results for observation 10,用以校对结果sum wage if inrange(age, age[10]-1, age[10]+1) & race == race[10] & industry == industry[10] & _n != 10

* calculate over the whole sample and list results for test observationsrangestat mwage = wage (count) wage, interval(age -1 1) excludeself by(race industry)list age *wage* in 10

特定年份其他公司的平均投资额。

webuse grunfeld, clearrangestat (median) invest, interval(year 0 0) excludeself

值得注意的是,将 lowhigh 都设置为 0 将为当前观察值选择所有具有相同年份的观测值。当指定 excludeself 选项时,将忽略每个当前观测值变量 invest 的值。

在滚动的时间范围内进行回归。可以使用内置函数 (reg) 在滚动的时间窗口内执行基本的普通最小二乘线性回归 (带有常数项)。

webuse grunfeld.dta, clearrangestat (reg) invest mvalue kstock, interval(year -6 0) by(company)

* check results for observation 15,用以校对结果list in 15regress invest mvalue kstock if inrange(year, year[15]-6, year[15]) ///        & company == company[15]

根据每日数据,计算月度协方差。可以使用内置函数 (cov) 来获取两个变量的协方差。

* fake data on 100 firms for 50 months with 21 daily returns per monthclearset seed 123123set obs 100gen long firm = _nexpand 50bysort firm: gen month = _nexpand 21bysort firm month: gen ret_day = _ngen return = runiform() if runiform() < .99gen weight = runiform()egen firm_month = group(firm month)

rangestat (cov) return weight, interval(firm_month 0 0) describelist cov_x in 1

* compare with results using -correlate- for first and last observation,用以校对corr return weight if firm_month == firm_month[1], covariancedis r(cov_12)

3.5 与 tsegen 对比

tsegenrangestat 之间在功能上存在一些重叠。两者都可以计算滚动时间范围内的统计信息。

webuse grunfeld.dta, cleartsegen double inv_m5b = rowmean(L(0/4).invest)rangestat (mean) invest, interval(year -4 0) by(company)assert inv_m5b == invest_mean

通常,tsegen 能更有效地处理时间序列数据,并且 egen 函数可同时处理所有观测值。但是,随着时间窗口的增加,tsegen 将生成更多的临时变量,tsegen 的效率会降低。此外,rangestat 的语法更加灵活,并且 rangestat 可以同时计算多个变量的多个统计信息。

webuse grunfeld, clear

rangestat (sd) sd_inv=invest kstock (count) invest kstock, interval(year -4 0) by(company)

4. 参考文献

温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。

  • Jann B. MOREMATA: Stata module (Mata) to provide various functions[J]. 2005. -Link-
  • Cox N J. Stata tip 51: Events in intervals[J]. The Stata Journal, 2007, 7(3): 440-443. -PDF-
  • Cox N J. Speaking Stata: Rowwise[J]. The Stata Journal, 2009, 9(1): 137-157. -PDF-
  • Cox N J. Speaking Stata: The limits of sample skewness and kurtosis[J]. The Stata Journal, 2010, 10(3): 482-495. -PDF-
  • Cox N J. Speaking Stata: Compared with…[J]. The Stata Journal, 2011, 11(2): 305-314. -PDF-
  • Cox N J. Speaking Stata: Self and others[J]. The Stata Journal, 2014, 14(2): 432-444. -PDF-

5. 相关推文

Note:产生如下推文列表的命令为:
lianxh 滚动 循环 求和 多久能跑完 runby sumup, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。

  • 专题:数据处理
    • 滚动吧统计量!Stata数据处理
    • Stata数据处理:各种求和方式一览
  • 专题:Stata程序
    • Stata程序:我的程序多久能跑完?
    • Stata:runby - 一切皆可分组计算!
    • statsby: 不用循环语句的循环
  • 专题:结果输出
    • sumup:快速呈现分组统计量
  • 专题:回归分析
    • Stata:滚动回归的五个命令-rolling
(0)

相关推荐