Bookmark and Share

Notice: On March 31, it was announced that Statalist is moving from an email list to a forum. The old list will shut down at the end of May, and its replacement, statalist.org is already up and running.


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: st: create local macros named after the values of a categorial variable


From   Sergiy Radyakin <serjradyakin@gmail.com>
To   statalist@hsphsun2.harvard.edu
Subject   Re: st: create local macros named after the values of a categorial variable
Date   Thu, 12 Aug 2010 18:14:37 -0400

Hi, Oliver,

I am not sure what exactly you want to achieve (beyond generating the
codes, how are they going to be used), but the second way is wrong.
note that if the code of a city happens to be less than your N, then
it will override some other code.

See it with the city codes 3,5,7.
For code 3 (i=1) your code would state smth like:
local 3 = 1
and this will override the [still unprocessed] local 3 which holds the value 7.

Deleting the "macros no longer needed" is not correct, since they may
coincide with the codes (in your data you may be sure they don't but
what if the codes change next year?).
Note that the program you've posted does not print the output message
correctly, but only:
For City Code 1 the value of the local macro is
For City Code 2 the value of the local macro is
For City Code 3 the value of the local macro is

which is not what you want, so don't self-destruct what you constructed.

If it is absolutely necessary to use locals (e.g. not matrices) put a
prefix and generate locals city101=1, city103=2, city105=3,....=N

The following code should be sufficient for your task:
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
levelsof `varname',local(levs)
forval i=1/`:word count `levs'' {
  local city`:word `i' of `levs'' "`i'"	
}
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
you can remove the "city" if you don't want the prefix for some reason
(the benefit of it is that you can "macro drop city*" when you don't
need them anymore, but locals are dropped anyways). However still
think why do you need the locals.

Best, Sergiy Radyakin


On Thu, Aug 12, 2010 at 9:23 AM, Oliver Jones
<ojones@wiwi.uni-bielefeld.de> wrote:
> Hi Statalist,
>
> while working on a programming problem a came in need
> of creating a set of local macros that are
>  i) named after the values of a categorial variable,
>    e.g. city codes
> ii) contain the integer values from 1 to N, where N is
>    the number of distinct city codes
>
> I worked out to alternatives that do the job, but would
> very much appreciate to get any feedback telling me if
> there exists some third alternative that is faster
> (in terms of computing time).
>
> Here is an example of what I do:
> -------------begin example-----------------------------
> clear
> set obs 3
> local varname = "city_code"
> gen `varname' = _n
> expand = 4
> list, abbreviate(9)
>
> preserve
> ******
> *
> * Alternative 1 (sort and keep)
> display "Start alternative 1"
> sort `varname'
> by `varname': gen byte index = _n
> keep if index == 1
> quietly count
> forvalues i = 1/`r(N)' {
>        local macro_name = `varname'[`i']
>        local `macro_name' = `i'
>        display "For City Code " `varname'[`i'] " the" ///
>                " value of the local macro is ``macro_name''"
> }
> display "end"
> * end
> ***
>
> restore
> ******
> *
> * Alternative 2 (levelsof)
> display "Start alternative 2"
> levelsof `varname'
> tokenize `r(levels)'
> * Now we got one local macro for each of the
> * city_codes, named 1, 2, ... , N.
> * But we want to exchange the names
> * of the macros by their values (the city_codes)
> * and vice versa.
>
> * get the number of different city_codes
> local N_citys = 1
> while "``N_citys''" != "" {
>        local ++N_citys
> }
> local --N_citys
> dis "{text}Number of distinct codes: {result}`N_citys'"
>
> forvalues i = 1/`N_citys'{
>        local new_mac_name = ``i''
>        local `new_mac_name' = `i'
>        local `i'       //delete the macros we no longer need
>        display "For City Code " `new_mac_name' " the" ///
>                " value of the local macro is {result}``new_mac_name''"
> }
> display "end"
> * end
> ***
> ---------------end example-----------------------------
>
> The datasets for which this is needed are quite big: 30 million observations
> each year and I got datasets for 24 years.
> The number of macros to be created amounts to approx. 330, i.e. 330
> different
> city codes. But this number is not constant in each year.
>
> So far alternative 1 (sort and keep) needs about 6 minutes to run and is
> outperformed by alternative 2 (levelsof) which need about 1 minutes.
>
> Kind regards
> Oliver
>
> *
> *   For searches and help try:
> *   http://www.stata.com/help.cgi?search
> *   http://www.stata.com/support/statalist/faq
> *   http://www.ats.ucla.edu/stat/stata/
>

*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/


© Copyright 1996–2014 StataCorp LP   |   Terms of use   |   Privacy   |   Contact us   |   Site index