滚动计算: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. 简介
rangeruan
和 rangestat
都可以进行滚动计算。
其中,rangestat
可以基于退化窗口、滚动窗口、递归窗口、反向递归窗口或特定窗口进行计算,可以完美使用 Stata 中的内置函数。为了提升运行速度,还可以直接使用自定义的 Mata 函数。在大型数据面前,比 tsegen
具有更高的执行效率。
rangerun
命令可以完成与 rangestat
相同的功能,但 rangestat
只能使用内置函数,或者编写的 Mata 函数。rangerun
执行速度比 rangestat
稍慢,但它更灵活,因为 rangerun
可以使用自定义函数。对于大型数据,rangerun
比 rolling
、statsby
和循环,具有明显的效率优势。
接下来,本文将具体介绍上述命令的应用。
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
对比
rangerun
与 rangestat
非常相似,不过在使用 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)
,当然也可以是其他形式。同时可以看出,rangerun
比 statsby
速度快。
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
值的观测值来计算统计数据。在这里,我们将 low
和 high
的值同时设为 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
特定观察间隔。low
和 high
还可以根据变量设定。以下示例查找 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
支持 if
和 in
限定符。
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
值得注意的是,将 low
和 high
都设置为 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
对比
tsegen
和 rangestat
之间在功能上存在一些重叠。两者都可以计算滚动时间范围内的统计信息。
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