在Stata中,我想为该月的第25个日历日生成一个指标,如果该日历日属于周末或假日,则生成前一个工作日。我在Stata中使用商业日历,在非工作日产生缺失值。
最有效的脚本是什么,而不是迭代地做这样的事情:
gen d25 = d == 25
replace d25 = cond(d[_n+1]==25 & date[_n+1]==.,1,d25)
Etc...
答案 0 :(得分:2)
这是一个如何做到这一点的例子:
sysuse sp500, clear
keep date
gen in_bcal=1
tsset date
tsfill
gen day25=cond(day(date)==25,1,0)
drop if missing(in_bcal) & day25==0
sort date
replace day25=day25[_n+1] if missing(in_bcal[_n+1])
drop if missing(in_bcal)
drop in_bcal
这可能会以更聪明的方式完成。
答案 1 :(得分:2)
作为@Dimitriy答案的补充,我想解决两个问题:
1。我对原始海报问题的解释是他开始使用商业日历。因此,问题在于标记商业日历中可能存在或不存在的一个月中的任意日期(数字)。如果它不存在,那么我们标记前一个工作日。
如果是这种情况,那么我们需要对原始代码进行少量添加,因为如果涉及业务日历,tsfill
将无法按预期工作。 (sp500
数据库date
变量不是describe
将显示的业务日历。)例如:
clear all
set more off
*----- example data -----
set obs 19
gen bdate = _n
format bdate %tbsimple // format as "simple" business calendar
*----- tsfill -----
tsset bdate
tsfill
list
在这种情况下, tsfill
不会填写任何内容;它不会填写非工作日。这些日子已被日历划掉,因此无需填写。我们需要:
gen rdate = dofb(bdate, "simple")
format rdate %td
将商家日历日期转换为常规日期。然后我们可以使用常规日期变量rdate
继续使用像Dimitriy这样的代码。
2。第二个问题是,如果系列的最后一次观察恰好是我们想要标记的那一天,那么Dimitriy的代码将导致丢失。这可以通过查找第31天而不是25来检查。2001年12月将缺少第31天。
下面是一个解决这两个问题的完整示例,希望不会增加任何错误。当然,Dimitriy对于一般(正确)的想法都很有用,任何错误都是我自己的。
clear all
set more off
*----- example data -----
set obs 19
gen bdate = _n
format bdate %tbsimple // format as "simple" business calendar
list, sep(0)
*----- what you want -----
gen rdate = dofb(bdate, "simple") // from business to regular
format rdate %td
tsset rdate
tsfill
gen day6 = (day(rdate) == 6)
drop if missing(bdate) & !day6
replace day6 = 1 if missing(bdate[_n+1]) & day6[_n+1] == 1
drop if missing(bdate)
list, sep(0)