How to rename many variables with string suffixes

ben picture ben · Dec 3, 2012 · Viewed 23.5k times · Source

In Stata, I have a set of variables that all begin with pkg. In their current state, their endings are numeric: pkg1, pkg2, pkg3, pkg4 and so on.

I need to change all of these variables' endings to strings: pkgmz, pkggmz, pkgsp, pkgsptc etc.

I have a column of these string endings, which I can designate as a local list.

For example:

local croplist mz gmz sp sptc mil cof suk tea ric

How do I change the numeric endings to the string endings?

My guess at the code can be found below and the ??? indicate where I am stumped:

local croplist crops mz gmz sp sptc mil cof suk tea ric

foreach x of varlist pkg* {
    local new1 = substr(`x', 1, 3)
    local new2 = ???
    rename `x' ``new1'`new2''
    label var ``new1'`new2'' "Avg district level `new2' price"
}

I wonder if it would be better to utilize the regexr() command, but can't think of a way to include it.

Any help is appreciated.

Answer

Nick Cox picture Nick Cox · Dec 3, 2012

There is no need here to invoke regular expressions. You have the new suffixes; the prefix pkg is always the same, so the labour of extracting it repeatedly is unnecessary. The heart of the problem is cycling over two lists at once. Here is one way to fix your code.


local croplist mz gmz sp sptc mil cof suk tea ric
local j = 1 
foreach x of varlist pkg* {
    local sffx : word `j' of `croplist' 
    rename `x' pkg`sffx'
    label var pkg`sffx' "Avg district level `sffx' price"
    local ++j 
}

Note also rename in Stata 12+ can handle this; regexr() is a function, not a command; a more general discussion in http://www.stata-journal.com/sjpdf.html?articlenum=pr0009 (a little out-of-date, but relevant on the main issue); you have too many quotation marks on your rename command, so it wouldn't work.

EDIT 30 July 2018

I tend now more often to use gettoken:

local croplist mz gmz sp sptc mil cof suk tea ric
foreach x of varlist pkg* {
    gettoken sffx croplist: croplist
    rename `x' pkg`sffx'
    label var pkg`sffx' "Avg district level `sffx' price"
}

The local macro croplist is a stack. Each time around the loop we take the top item from the stack and leave the rest for the next time. Each time around the loop