*! version 1.0.8 31may2011 * 1.0.7 -labelsof- no longer needed * replaced with mata function * 1.0.8 changes in -vallab- option (add -nodelete-) program strrec ,sclass version 11.1 syntax anything(equalok id = "varlist (rule) [(rule)]") [if][in] /// [, PREfix(name) Generate(namelist) REPLACE /// SUB WILDcards CASEsensitive STRing /// DEFine(name) noLabel /// ELSEMISS COPYrest /// VALLab VLab LABREC noDELete] local alloptions replace sub casesensitive string label copyrest /// elsemiss vallab local binopt rplc sub case str nolab copy elsemiss vallab /*get input and do some checks -------------------------------*/ local uif `if' local uin `in' gettoken vars anything : anything ,parse("(") if `"`vars'"' == "(" errorexit varlist unab varlist : `vars' loc dup : list dups varlist loc varlist : list varlist - dup if `"`anything'"' == "" errorexit rules if `"`wildcards'"' != "" local sub sub if "`labrec'" != "" | "`vlab'" != "" local vallab vallab if "`vallab'"' == "" { marksample touse ,nov qui count if `touse' if r(N) == 0 errorexit noobs drop `touse' if "`replace'" == "" { if "`generate'" != "" { if "`prefix'" == "" confirm new var `generate' else { foreach g of local generate { confirm new var `prefix'`g' } } local ngen : word count `generate' local nvar : word count `varlist' if `ngen' != `nvar' { local fewmany = cond(`ngen' < `nvar' /// ,"few" ,"many") errorexit "`fewmany'" } } else { if "`prefix'" == "" local prefix "r_" foreach v of local varlist { confirm new var `prefix'`v' } } } else { local prefix "" local generate `varlist' } } else { local string "" local label "" } sret clear /*options to s() -----------------*/ forval j = 1/`: word count `alloptions'' { local opt_`: word `j' of `binopt'' = /// ("``: word `j' of `alloptions'''" != "") sret local opt_`: word `j' of `binopt'' /// `opt_`: word `j' of `binopt''' } srgetrules `anything' /*define mode and select subroutine ------------------------------------*/ local mode2 = cond(`s(mode)' == 1 /// , cond(`s(opt_vallab)' == 1 ,3 ,1) /// ,cond(`s(opt_vallab)' == 1 ,4 ,2)) if `s(mode)' != `mode2' sret local mode `mode2' if `s(mode)' <= 2 srstrrec `varlist' `uif' `uin' /// , prefix(`prefix') generate(`generate') define(`define') else srvallab `varlist' ,`delete' sret clear end program srstrrec syntax varlist [if][in] /// [, Prefix(name) Generate(namelist) DEFine(name)] marksample touse ,nov tempvar tmp_var rplc_var local varcnt 0 foreach var of local varlist { local ++varcnt cap confirm str var `var' if _rc { di "{txt}note: omitted numeric variable {res}`var'" continue } /*copy var to make changes ---------------------------*/ qui g `tmp_var' = cond(`s(opt_case)' == 1 /// ,`var' /// ,itrim(trim(lower(`var')))) /*check substrings and change tmp_var --------------------------------------*/ if `s(opt_sub)' { forval j = 1/`s(nrules)' { tokenize `"`s(_org_`j')'"' ,parse(",") local tok 0 while `"``++tok''"' != "" { qui replace `tmp_var' = "``tok''" /// if strmatch(`tmp_var',"``tok''") local ++tok } } } /*name new var ---------------*/ local newvar = cond("`generate'" == "" /// ,"`prefix'`var'" ,"`prefix'`: word `varcnt' of `generate''") di "{res}`newvar'" /*settings -----------*/ if !`s(opt_copy)' local cpy if `touse' else local cpy "" local oldvarlab : var lab `var' if `s(opt_rplc)' { order `tmp_var' ,before(`var') if `s(mode)' == 1 { drop `var' qui g `newvar' = . } else { if !`s(opt_elsemiss)' { qui g `rplc_var' = `var' `cpy' drop `var' qui g `newvar' = `rplc_var' drop `rplc_var' } else { local oldtype : type `var' drop `var' qui g `oldtype' `newvar' = "" } } order `newvar' ,before(`tmp_var') } else { if `s(mode)' == 1 qui g `newvar' = . else { local oldtype : type `var' if `s(opt_elsemiss)' qui g `oldtype' `newvar' = "" else qui g `newvar' = `var' `cpy' } } /*recode procedure -------------------*/ if `s(mode)' == 1 { forval j = 1/`s(nrules)' { replace `newvar' = `s(_des_`j')' /// if inlist(`tmp_var',`s(_org_`j')') & `touse' if !`s(opt_nolab)' { local tmpnam = cond("`define'" == "" /// ,"`newvar'" ,"`define'") cap assert `s(_des_`j')' == int(`s(_des_`j')') if !_rc & `s(_des_`j')' != . /// lab def `tmpnam' /// `s(_des_`j')' "`s(_lab_`j')'" ,modify } } if !`s(opt_nolab)' lab val `newvar' `tmpnam' } else { forval j = 1/`s(nrules)' { replace `newvar' = `"`s(_des_`j')'"' /// if inlist(`tmp_var',`s(_org_`j')') & `touse' } } drop `tmp_var' qui compress `newvar' if `"`oldvarlabel'"' != "" lab var `newvar' `"`oldvarlabel'"' } end program srvallab ,sclass syntax varlist [ ,noDELete] tempname _vals /*strip duplicates -------------------*/ loc dup : list dups varlist loc varlist : list varlist - dup /*get variable list for value labels (borrowed from uselabel.ado) ------------------------------------------------------------------*/ foreach var of varlist * { local lbl_vars : val lab `var' if "`lbl_vars'" != "" { sret local `lbl_vars' `s(`lbl_vars')' `var' if (`s(mode)' == 3) loc vars2copy `vars2copy' cpy_`var' } else local omitvars `omitvars' `var' } /*create copy of variables to be recoded -----------------------------------------*/ if (`s(mode)' == 3) { tempvar `vars2copy' foreach tv in `vars2copy' { loc ovar = substr("`tv'", 5, .) loc typ : t `ovar' qui g `typ' ``tv'' = `ovar' } } /*main loop over variables ---------------------------*/ foreach var of local varlist { if `: list posof "`var'" in omitvars' != 0 continue if `: list posof "`var'" in varsdone' != 0 continue local tmp_lab_nam : val lab `var' cap la li `tmp_lab_nam' if _rc { if _rc == 111 continue else errorexit other `var' `tmp_lab_nam' _rc } mata : st_vlload("`tmp_lab_nam'", vl = ., lbltxt = .) mata : st_matrix("`_vals'", vl) di "{res}`tmp_lab_nam' {txt}({res}`s(`tmp_lab_nam')'{txt})" /*get labels (name,text and integer part) ------------------------------------------*/ forval j = 1/`= rowsof(`_vals')' { loc tmp_lab_val = `_vals'[`j', 1] local tmp_lab_txt : lab `tmp_lab_nam' `tmp_lab_val' local tmp_lab_txt : subinstr loc tmp_lab_txt "`" "'" ,all if !`s(opt_case)' /// local tmp_lab_txt = itrim(trim(lower(`"`tmp_lab_txt'"'))) /*sub option -------------*/ if `s(opt_sub)' { local skip "" forval j = 1/`s(nrules)' { `skip' tokenize `"`s(_org_`j')'"' ,parse(",") local tok 0 while `"``++tok''"' != "" { if strmatch(`"`tmp_lab_txt'"',"``tok''") { local tmp_lab_txt `"``tok''"' local skip continue ,break `skip' } local ++tok } } } /*recode value labels ----------------------*/ forval j = 1/`s(nrules)' { if inlist("`tmp_lab_txt'",`s(_org_`j')') { if `s(mode)' == 4 { lab def `tmp_lab_nam' /// `tmp_lab_val' "`s(_des_`j')'" ,modify foreach addv in `s(`tmp_lab_nam')' { loc varsdone `varsdone' `addv' } } else if (`s(mode)' == 3) /// & (`s(_des_`j')' != `tmp_lab_val') { if ("`delete'" == "") { lab def `tmp_lab_nam' `tmp_lab_val' "" ,modify } cap assert `s(_des_`j')' == int(`s(_des_`j')') if !_rc & `s(_des_`j')' != . { lab def `tmp_lab_nam' `s(_des_`j')' /// "`s(_lab_`j')'" ,modify } /*recode variables -------------------*/ foreach addv in `s(`tmp_lab_nam')' { replace `addv' = `s(_des_`j')' /// if `cpy_`addv'' == `tmp_lab_val' local varsdone `varsdone' `addv' } } } } } } end program srgetrules ,sclass local nrules 0 while `"`0'"' != "" { local ++nrules gettoken err_r : 0 ,match(m) gettoken rule 0 : 0 ,match(m) local tok "" while `"`tok'"' != "=" { gettoken tok rule : rule ,parse(`"=" "') if `"`tok'"' != "=" { local sep = cond(`"`org`nrules''"' == "" ,"",",") if !`s(opt_case)' /// local tok = itrim(trim(lower(`"`tok'"'))) local org`nrules' `"`org`nrules''`sep'"`tok'""' } if `"`tok'"' == "" errorexit invalidrule `"`err_r'"' } if (`"`org`nrules''"' == "") | (`"`rule'"' == "") /// errorexit invalidrule `"`err_r'"' tokenize `"`rule'"' ,parse(`"" "') chkset_mode `"`1'"' `nrules' `"`err_r'"' local des`nrules' `"`1'"' if `s(mode)' == 1 & !`s(opt_nolab)' { if `"`2'"' == "" { gettoken lab`nrules' : org`nrules' ,parse(",") } else local lab`nrules' `"`2'"' } } sret local nrules `nrules' forval j = 1/`nrules' { foreach x in org des lab { sret local _`x'_`j' "``x'`j''" } } end program chkset_mode ,sclass if !`s(opt_str)' { cap conf num `1' if _rc { cap as `1' == int(`1') if _rc { if `2' == 1 { local mode 2 sret local mode `mode' } if `s(mode)' == 1 errorexit invalidrule `"`3'"' } else if `2' == 1 local mode 1 } else if `2' == 1 local mode 1 } else local mode 2 if `2' == 1 & "`s(mode)'" == "" sret local mode `mode' end program errorexit if "`1'" == "noobs" { di "{err}no observations" exit 2000 } if inlist("`1'","varlist","rules") { di `"{err}`1' expected"' exit 198 } if inlist("`1'","few","many") { di "{err}option generate() : too `1' names specified" exit 198 } if "`1'" == "invalidrule" { di `"{err}invalid rule: (`2');"' di `"all rules must either be "' /// `"("str" = # ["lbl"]) or ("str" = "newstr")"' exit 198 } if "`1'" == "other" { di "{err}`2' (`3')" exit `4' } end