*! version 1.0 27may2014 Joseph Canner /* renvarlab: Renames variables, with option of using variable labels to create new variable names Usage: renvars varlist [, transformation options] Author: Joseph Canner Johns Hopkins University School of Medicine Department of Surgery Center for Surgical Trials and Outcomes Research jcanner1@jhmi.edu Acknoweldgements: Adapted from -renvars- (SSC) by Nicholas J. Cox and Jeroen Weesie Version 1.0 May 27, 2014 */ program renvarlab version 8 // "/" is allowed, but not documented gettoken oldvars 0 : 0 , parse("\/,") if `"`oldvars'"' == "\" | `"`oldvars'"' == "/" | `"`oldvars'"' == "," { local 0 `"`oldvars' `0'"' local oldvars "_all" } unab oldvars : `oldvars' local nold : word count `oldvars' tokenize `oldvars' gettoken punct 0 : 0, parse("\/,") if `"`punct'"' != "\" & `"`punct'"' != "/" & `"`punct'"' != "," { di as err "illegal syntax: " /// `""\ varlist" or transformation option expected"' exit 198 } if `"`punct'"' == "\" | `"`punct'"' == "/" { /* one-to-one mapping */ syntax newvarlist [, Display TEST ] local nnew : word count `varlist' if `nold' != `nnew' { di as err /// "lists of old and new varnames unequal in length" exit 198 } local newvars `varlist' } else if `"`punct'"' == "," { /* transformation */ local 0 ", `0'" syntax , [ Upper Lower PREFix(str) POSTFix(str) /// SUFFix(str) PRESub(str) POSTSub(str) SUBst(str) /// PREDrop(str) POSTDrop(str) Trim(str) TRIMEnd(str) /// Map(str asis) SYmbol(str) Display TEST LABel ] if `"`symbol'"' == "" local symbol "@" if `"`map'"' != "" & !index(`"`map'"',`"`symbol'"') { di as err `"map() does not contain `symbol'"' exit 198 } // suffix is a synonym for postfix; issuing both // is not an error, so long as they agree if `"`suffix'"' != "" { if `"`postfix'"' != "" & `"`postfix'"' != `"`suffix'"' { di as err "postfix() and suffix() differ" exit 198 } local postfix `"`suffix'"' local suffix } local nopt : word count `upper' `lower' `prefix' `postfix' `suffix' `predrop' `postdrop' `trim' `trimend' local nopt = `nopt' + (`"`map'"' != "") + (`"`presub'"' != "") + (`"`postsub'"' != "") + (`"`subst'"' != "") if (`nopt' != 1) & !(`nopt'==0 & "`label'"!="") { di as err "exactly one transformation option should be specified" exit 198 } if `"`subst'"' != "" { local srch : word 1 of `subst' local repl : word 2 of `subst' } if `"`presub'"' != "" { local srch : word 1 of `presub' local repl : word 2 of `presub' local nsrch = length(`"`srch'"') } if `"`postsub'"' != "" { local srch : word 1 of `postsub' local repl : word 2 of `postsub' local nsrch = length(`"`srch'"') } // varlist is already tokenized local i 1 local oldvars local newvars while "``i''" != "" { local oldname="``i''" if "`label'" != "" { local source : var label ``i'' // If there are no other transformation options, make the variable out of the label if `nopt'==0 { local newname = strtoname("`source'") } } else { local source = "``i''" } if "`upper'" != "" { local newname = upper("`source'") } else if "`lower'" != "" { local newname = lower("`source'") } else if `"`prefix'"' != "" { local newname `"`prefix'`source'"' } else if `"`postfix'"' != "" { local newname `"`source'`postfix'"' } else if `"`subst'"' != "" { local newname : /// subinstr local source `"`srch'"' `"`repl'"', all } else if `"`presub'"' != "" { if "`srch'" == substr("`source'",1,`nsrch') { local newname = /// `"`repl'"' + substr("`source'", `nsrch' + 1, .) } else local newname `source' } else if `"`postsub'"' != "" { if `"`srch'"' == substr("`source'",-`nsrch',.) { local newname = /// substr("`source'",1,length("`source'")-`nsrch') + `"`repl'"' } else local newname `source' } else if `"`predrop'"' != "" { confirm integer number `predrop' local newname = substr("`source'", 1 + `predrop', .) } else if `"`postdrop'"' != "" { confirm integer number `postdrop' local newname = /// substr("`source'", 1, length("`source'") - `postdrop') } else if `"`trim'"' != "" { confirm integer number `trim' local newname = substr("`source'", 1, `trim') } else if `"`trimend'"' != "" { confirm integer number `trimend' if `trimend' <= length("`source'") { local newname = substr("`source'", -`trimend', .) } else local newname "`source'" } else if `"`map'"' != "" { // Build map expression local mapexp : /// subinstr local map "`symbol'" "`source'", all // Evaluate expression and test validity capture local newname = `mapexp' if _rc { di as err "Error in map" exit _rc } } // Check to make sure the result is a valid variable name capture confirm name `newname' if _rc { di as err "Resulting variable name (`newname') is invalid" exit _rc } // Check to make sure the new name is either the same as the old name or represents a new unique name capture confirm new var `newname' if _rc & "`newname'"!="`oldname'" { di as err "Variable name (`newname') already exists." exit _rc } if "``i''" != "`newname'" { local oldvars `oldvars' ``i'' local newvars `newvars' `newname' } local ++i } // One last check to make sure new list consists of all new names if `"`newvars'"' != "" { confirm new var `newvars' tokenize `oldvars' } else { di as txt "No renames necessary: all new names match old names" exit 0 } } /* end of syntax processing for transformation */ if "`test'" == "" { nobreak { local nold : word count `oldvars' forv i = 1 / `nold' { local newname : word `i' of `newvars' if "`display'" != "" { di as txt " {ralign 32:``i''} -> `newname'" } rename ``i'' `newname' } } } else { di as txt /// "specification would result in the following renames:" local nold : word count `oldvars' forv i = 1 / `nold' { local newname : word `i' of `newvars' di as txt " {ralign 32:``i''} -> `newname'" } } end exit