You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
4.4 KiB
Plaintext
169 lines
4.4 KiB
Plaintext
7 months ago
|
*! 1.3.0 NJC 6 Sept 2005
|
||
|
* 1.2.1 NJC 29 July 2003
|
||
|
* 1.2.0 NJC 4 July 2001
|
||
|
* 1.1.0 NJC 7 June 2001
|
||
|
program todate
|
||
|
version 8
|
||
|
syntax varlist [if] [in], Pattern(string) Generate(string) ///
|
||
|
[ Format(string) Cend(numlist int >200 <=10000 max=1) ]
|
||
|
|
||
|
// existing and new varlists
|
||
|
tokenize `varlist'
|
||
|
local nvars : word count `varlist'
|
||
|
|
||
|
// do before second -syntax-
|
||
|
marksample touse, novarlist
|
||
|
|
||
|
local 0 "`generate'"
|
||
|
syntax newvarlist
|
||
|
|
||
|
if `nvars' != `: word count `varlist'' {
|
||
|
di as err "number of new variables not equal to" _c
|
||
|
di as err " number of existing variables"
|
||
|
exit 198
|
||
|
}
|
||
|
|
||
|
// partial test of format
|
||
|
if "`format'" != "" {
|
||
|
capture display `format' 1
|
||
|
if _rc {
|
||
|
di as err "invalid format()"
|
||
|
exit 120
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// parse pattern into m d y h q w elements
|
||
|
// indulge upper case
|
||
|
local pattern = lower("`pattern'")
|
||
|
local plength = length("`pattern'")
|
||
|
|
||
|
forval i = 1 / `plength' {
|
||
|
local p = substr("`pattern'",`i',1)
|
||
|
|
||
|
if "`p'" == "m" local mlist "`mlist' `i'"
|
||
|
else if "`p'" == "d" local dlist "`dlist' `i'"
|
||
|
else if "`p'" == "y" local ylist "`ylist' `i'"
|
||
|
else if "`p'" == "h" local hlist "`hlist' `i'"
|
||
|
else if "`p'" == "q" local qlist "`qlist' `i'"
|
||
|
else if "`p'" == "w" local wlist "`wlist' `i'"
|
||
|
else {
|
||
|
di as err "invalid pattern"
|
||
|
exit 198
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// allow mdy yh yq ym yw permutations
|
||
|
foreach i in m d y h q w {
|
||
|
if "``i'list'" != "" {
|
||
|
local ptype "`ptype'`i'"
|
||
|
local pels "`pels' `i'"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if !inlist("`ptype'", "yh", "yq", "my", "yw", "mdy") {
|
||
|
di as err "invalid pattern type: `ptype'"
|
||
|
exit 198
|
||
|
}
|
||
|
if "`ptype'" == "my" local ptype "ym"
|
||
|
|
||
|
// contiguous digits will have range == # elements - 1
|
||
|
foreach i in `pels' {
|
||
|
local `i'1 : word 1 of ``i'list'
|
||
|
local `i'len : word count ``i'list'
|
||
|
local last : word ``i'len' of ``i'list'
|
||
|
local range = `last' - ``i'1'
|
||
|
local range2 = ``i'len' - 1
|
||
|
if `range' != `range2' {
|
||
|
di as err "`i' digits not contiguous in pattern"
|
||
|
exit 198
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// year digits and cend() compatible?
|
||
|
if `ylen' != 4 & "`cend'" == "" {
|
||
|
di as err "`ylen' digit years: need cend() option?"
|
||
|
exit 198
|
||
|
}
|
||
|
else if `ylen' == 4 & "`cend'" != "" {
|
||
|
di as txt "4 digit years: cend() option ignored"
|
||
|
local cend
|
||
|
}
|
||
|
|
||
|
// for each variable in original varlist
|
||
|
qui forval i = 1 / `nvars' {
|
||
|
tempvar strdate datelen touse2
|
||
|
|
||
|
// markout separately for each variable
|
||
|
gen byte `touse2' = `touse'
|
||
|
markout `touse2' ``i'', strok
|
||
|
|
||
|
// working string variable copy of date variable
|
||
|
capture confirm string variable ``i''
|
||
|
if _rc gen `strdate' = string(``i'',"%12.0g") if `touse2'
|
||
|
else gen `strdate' = trim(``i'') if `touse2'
|
||
|
local v "``i''"
|
||
|
local `i' "`strdate'"
|
||
|
|
||
|
// how long is date variable?
|
||
|
gen `datelen' = length(``i'')
|
||
|
su `datelen' if `touse2', meanonly
|
||
|
local range = r(max) - r(min)
|
||
|
local min = r(min)
|
||
|
local max = r(max)
|
||
|
|
||
|
if `max' != `plength' {
|
||
|
noi di as res "`v': " ///
|
||
|
as txt "length does not match pattern"
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
// range == 0 is no problem
|
||
|
if `range' == 1 { /* leading zero needs to be supplied? */
|
||
|
replace `strdate' = "0" + `strdate' ///
|
||
|
if `datelen' == `min' & `touse2'
|
||
|
}
|
||
|
else if `range' >= 2 { /* range of lengths >= 2 => skip this */
|
||
|
noi di as res "`v': " ///
|
||
|
as txt "length too variable to handle"
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
// construct month, day, year, half, quarter, week as needed
|
||
|
foreach j in `pels' {
|
||
|
tempvar `j'
|
||
|
gen ``j'' = real(substr(``i'',``j'1',``j'len'))
|
||
|
}
|
||
|
|
||
|
if "`cend'" != "" {
|
||
|
local c1 = int(`cend' / 100)
|
||
|
local c2 = mod(`cend',100)
|
||
|
replace `y' = ///
|
||
|
`y' + 100 * cond(`y' <= `c2', `c1', `c1' - 1)
|
||
|
}
|
||
|
|
||
|
// generate new variable
|
||
|
local newvar : word `i' of `varlist'
|
||
|
if "`ptype'" == "mdy" {
|
||
|
gen `newvar' = mdy(`m',`d',`y') if `touse2'
|
||
|
}
|
||
|
else {
|
||
|
local o = substr("`ptype'",2,1)
|
||
|
gen `newvar' = y`o'(`y',``o'') if `touse2'
|
||
|
}
|
||
|
|
||
|
if "`format'" != "" format `format' `newvar'
|
||
|
else {
|
||
|
if index("`ptype'", "d") format %d `newvar'
|
||
|
else if index("`ptype'", "w") format %tw `newvar'
|
||
|
else if index("`ptype'", "m") format %tm `newvar'
|
||
|
else if index("`ptype'", "q") format %tq `newvar'
|
||
|
else if index("`ptype'", "h") format %th `newvar'
|
||
|
}
|
||
|
|
||
|
_crcslbl `newvar' ``i''
|
||
|
|
||
|
drop `touse2'
|
||
|
}
|
||
|
end
|
||
|
|