*! strkeep v1.1 RChu 05apr2017 program define strkeep version 14.0 syntax varlist(min=1 str) [if] [in] /// [, GENerate(name) replace ///generate options Alpha LOWERcase UPPERcase Numeric keep(string) ///whitelist options STRLower STRUpper ///strlower() and strupper() options Sub(string)] //substitution option *Check generate options* if "`generate'"=="" & "`replace'"=="" { //No generate or replace specified di in red "strkeep: must specify {opt generate} or {opt replace}" error 197 } if "`generate'"!="" & "`replace'"!="" { //Both generate and replace specified di in red "strkeep: {opt generate} and {opt replace} are mutually exclusive" error 184 } if "`generate'"!="" { //If generate specified loc numofvars : list sizeof varlist if `numofvars'==1 { //Only cleaning one variable capture conf v `generate' if !_rc { di in red "strkeep: variable {it:`generate'} already exists, either drop or choose new name" error 110 } } else { //Cleaning multiple variables **Check to make sure stub length is not too long** if `=strlen("`generate'")+strlen("`numofvars'")'>32 { di in red "strkeep: stub {it:`generate'} too long for `numofvars' new variables" error 198 } **Check if all variables for generate are non-existent** forv i=1/`numofvars' { capture conf v `generate'`i' if !_rc { di in red "strkeep: variable {it:`generate'`i'} already exists, either drop or choose new stub" error 110 } } } } *Check strlower/strupper options* if "`strlower'"!="" & "`strupper'"!="" { di in red "strkeep: {opt strlower} and {opt strupper} may not be specified together" error 198 } *Check sub option* if strlen(`"`sub'"')>1 { di in red "strkeep: {opt sub} must be at most one character in length" error 198 } *Check whitelist options* if "`alpha'"=="" & "`lowercase'"=="" & "`uppercase'"=="" /// & "`numeric'"=="" & `"`keep'"'=="" { //Nothing to keep di in red "strkeep: must specify at least one whitelist option" error 197 } *Define whitelist option values* loc wl_lowercase = "abcdefghijklmnopqrstuvwxyz" loc wl_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" loc wl_alpha = "`wl_lowercase'`wl_uppercase'" loc wl_numeric = "0123456789" loc wl_keep = `"`keep'"' *Define whitelist* loc wl = `"`sub'"' //define whitelist, add any sub in foreach opt in alpha lowercase uppercase numeric keep { if `"``opt''"'!="" { //option specified loc wl = `"`wl'`wl_`opt''"' //add to whitelist } } *Process varlist* loc i = 1 tempvar new tempvar index qui g `new' = "" qui g `index' = . foreach var of var `varlist' { qui replace `new' = `var' `if' `in' qui replace `index' = indexnot(`new',`"`wl'"') qui su `index' **Clean var -- the magic!** while r(max)!=0 { qui replace `new' = substr(`new',1,`index'-1)+`"`sub'"'+substr(`new',`index'+1,.) /// if `index'>0 //if need to clean qui replace `index' = indexnot(`new',`"`wl'"') qui su `index' } **Perform strlower() or strupper() on new string** if "`strlower'"!="" { qui replace `new' = strlower(`new') } if "`strupper'"!="" { qui replace `new' = strupper(`new') } **Save cleaned var** if "`generate'"!="" { //generate if `numofvars'==1 { //only one var in varlist g `generate' = `new' } else { //multiple vars in varlist g `generate'`i++' = `new' } } else { //must be replace replace `var' = `new' `if' `in' } } end