*nearmrg.ado - performs nearest match merges of nearvar within exact matches of optional varlist *! version 2.1.1 E Booth Jan2011 ** version 2.1.0 E Booth Oct2011 ** version 2.0.1 M Blasnik Sep03 ** version 2.0.2 M Blasnik, K Smith Mar08 program define nearmrg syntax [varlist(default=none)] using , /// Nearvar(varname numeric) [TYPE(str asis)] /// [LIMit(str asis) GENMATCH(str asis) LOWer UPper ROundup * ] *--------------error checking if !inlist(`"`type'"', "_n", "1:1", "m:1", "1:m", "m:m") { loc type "m:1" di in yellow `"Merge Type not or incorrectly specified. Type [m:1] assumed. See {help merge} for more."' } if `"`genmatch'"'!=`""' confirm new var `genmatch' if `"`roundup'"'==`""' local eq = "=" if ((`"`lower'"'!=`""') + (`"`upper'"'!=`""') + (`"`roundup'"'!=`""'))>1 { di as err `"Cannot choose more than one of options {bf:roundup, lower, or upper}"' exit 198 } //end.check.opts *--------------specify varlist local fullvars `"`varlist' `nearvar'"' if `"`varlist'"' != `""' { local bycmd `"by `varlist': "' } **qui { *--------------master/work dataset (order lookup) tempvar order tempfile work gen double `order'=_n preserve keep `order' `fullvars' save `work' *--------------using data use `fullvars' `using', clear *---error check: _dstr master data nearvar: *cap confirm string var `nearvar' *if _rc ==0 _dstr `nearvar' , `string' xx(`stringdate') if mi(`nearvar') { di as err `"`nearvar' contains non-numeric chars, cannot destring (if `nearvar' is a date, convert using time-date functions)"' exit 198 } *noi desc sort `fullvars' cap isid `fullvars' if _rc { di as err "Variables: `fullvars' not unique in using dataset" error 459 } *--------------append master/work dataset to using append using `work' sort `fullvars' *--------------find nearest match first/last/merg/gen tempvar last next mrg gen clonevar `last'=`nearvar' if `order'==. clonevar `next'=`last' `bycmd' replace `last'=`last'[_n-1] if mi(`last') gsort `varlist' -`nearvar' `bycmd' replace `next'=`next'[_n-1] if mi(`next') //fix 'double' format condition// cap confirm numeric var `nearvar' noi di _rc if `"`lower'"' !=`""' gen double `gen'=cond(`nearvar'!=`next',`last',`next') if `"`upper'"' !=`""' gen double `gen'=cond(`nearvar'!=`last',`next',`last') if `"`upper'`lower'"' == `""' gen double `gen'=cond((`nearvar'-`last')<`eq'abs(`nearvar'-`next'),`last',`next') *---------------- local tmpfmt: format `nearvar' format `gen' `tmpfmt' drop if `order'==. sort `order' keep `order' `gen' save `work', replace /* now get the matching values into original data */ restore sort `order' if `c(version)' <11 merge `order' using `work' , _merge(`mrg') if `c(version)' >=11 merge `type' `order' using `work' , generate(`mrg') cap drop `mrg' /* now shuffle around the names to do the merge into the using dataset */ tempvar hold rename `nearvar' `hold' rename `gen' `nearvar' sort `fullvars' if `c(version)' <11 merge `fullvars' `using' , `options' if `c(version)' >=11 merge m:1 `fullvars' `using' , `options' rename `nearvar' `gen' rename `hold' `nearvar' *----------limit subprgm if `"`limit'"' != "" { tempvar diff gen `diff' = abs(`gen' - `nearvar') keep if `diff'<=`limit' } //end.limit.subprgm if "`genmatch'"!="" { clonevar `genmatch'=`gen' local text `"`upper'`lower' "' if `"`fullvars'"' !="" local text2 ", matched on `varlist'" label var `genmatch' `"nearest `text'match to `nearvar' `text2'"' } //end.genmatch.if **} //end qui end *--destring subprgm--* program define _dstr syntax varlist, [string xx(str asis)] if `"`string'"' != `""' & `"`stringdate'"' == "" { cap confirm string var `varlist' if _rc!=0 di as err `"`varlist' contains non-string variables"' cap confirm string var `varlist' if _rc==0 qui destring `varlist', replace force } //end string end /* NOTES * v2.1.1 = added limit to upper/lower match (e.g. within X number of days); updated to new merge syntax in Stata versions 11+; added TYPE option for merge type; added _dstr subprogram; (EAB) * v2.1.0 - fixed double format for cond() statements; fixed string option; fixed merge syntax change; fixed stringdate format change; created new options (EAB) * v2.0.2 - new variables now created in double precision. * - if genmatch() option specified, resulting variable is formatted to match nearvar. */