1

我想通过编写Stata代码来获得运行最大值。

我想我很接近:

gen ctrhigh`iv' = max(ctr, L1.ctr, L2.ctr, L3.ctr, ..., L`iv'.ctr)

如您所见,我的数据是时间序列并`iv'代表窗口(例如 5、10 或 200 天)

唯一的问题是您不能将包含数字的 varlist 或字符串传递给max. 例如,以下是不可能的:

local ivs 5 10 50 100 200
foreach iv in `ivs' {
    local vals
    local i = 1
    while (`i' <= `iv') {
        vals "`vals' `i'"
        local ++i
    }
    gen ctrhigh`iv' = max(varlist vals) //not possible
}

我将如何实现这一目标?

快速计算运行标准差的示例

* standard deviation of ctr, see http://en.wikipedia.org/wiki/Standard_deviation#Rapid_calculation_methods *
gen ctr_sq = ctr^2
by tid: gen ctr_cum = sum(ctr) if !missing(ctr)
by tid: gen ctr_sq_cum = sum(ctr_sq) if !missing(ctr_sq)
foreach iv in $ivs {
    if `iv' == 1 continue
    by tid: gen ctr_sum = ctr_cum - L`iv'.ctr_cum if !missing(ctr_cum) & !missing(L`iv'.ctr_cum)
    by tid: gen ctr_sq_sum = ctr_sq_cum - L`iv'.ctr_sq_cum if !missing(ctr_sq_cum) & !missing(L`iv'.ctr_sq_cum)
    by tid: gen ctrsd`iv' = sqrt((`iv' * ctr_sq_sum - ctr_sum^2) / (`iv'*(`iv'-1))) if !missing(ctr_sq_sum) & !missing(ctr_sum)
    label variable ctrsd`iv' "Rolling std dev of close ticker rank by `iv' days."
    drop ctr_sum ctr_sq_sum
}
drop ctr_sq ctr_cum ctr_sq_cum

注意:这不是一个精确的标准差,它是一个近似值。我意识到这与最大值有很大不同,但这可以作为如何处理大数据计算的说明。

4

2 回答 2

1

您的示例是时间序列数据,暗示您拥有tsset数据。你没有说你是否也有面板或纵向结构。我将假设最坏的情况并假设后者,因为它不会使代码变得更糟。所以,假设tsset id date。事实上,这与这里的代码无关,只是为了明确我的假设,id即标识符和date时间变量。

一个没有吸引力的方法是循环观察。假设窗口设置为 42。

  local window = 42 
  gen max = . 
  tsset id date 
  quietly forval i = 1/`=_N' { 
      su ctr if inrange(date, date[`i'] - `window', date[`i']) & id == id[`i'], meanonly 
      replace max = r(max) in `i' 
  } 

所以,用词也是如此:if within window的summarize它在同一个面板中(相同),并将最大值放在当前观察中。ctrdateid

meanonly选项没有很好地命名。它计算除平均值之外的一些其他量,最大值为一。但是您确实希望meanonly选择summarize尽可能快地进行。

请参阅我 2007 年关于间隔事件的论文,可在http://www.stata-journal.com/sjpdf.html?articlenum=pr0033免费获取

我说没有吸引力,但这种方法确实有一个优点,即一旦你理解了它就很容易使用。

我没有设置一个有很多参数的表达式max()。您以 200 为例,并没有说明您可能不会要求更多,据我所知,窗口长度可能没有上限,但该表达式的复杂程度会有限制。

如果我想到更好的方法,我会发布它。或者别人会......

于 2013-04-26T22:48:06.247 回答
0

似乎我可以将一串参数传递给 max,如下所示:

* OPTION 1: compute running max by days *
foreach iv in $ivs {

    * does not make sense for less than two days *
    if `iv' < 2 continue

    di "computing running max for ctr interval `iv'"

    * set high for this amount of days *
    local vars "ctr"
    forval i = 1 / `iv' {
        local vars "`vars', L`i'.ctr"
    }
    by tid: gen ctrh`iv' = max(`vars')

}


* OPTION 2: compute running max by days, ensuring that entire range is nonmissing *
foreach iv in $ivs {

    * does not make sense for less than two days *
    if `iv' < 2 continue

    di "computing running max for ctr interval `iv'"

    * set high for this amount of days *
    local vars "ctr"
    local condition "!missing(ctr)"
    forval i = 1 / `iv' {
        local vars "`vars', L`i'.ctr"
        local condition "`condition' & !missing(L`i'.ctr)"
    }
    by tid: gen ctrh`iv' = max(`vars') if `condition'

}

这计算得非常快,并且完全符合我的需要。

但是,如果您需要一个任意大的窗口,我认为您应该求助于尼克的回答。

于 2013-04-27T10:23:51.533 回答