aesir
aesir

Reputation: 565

Storing values in a macro variable

I'm using the levelsof command to identify unique values of a variable and stick them into a macro. Then later on I'd like to use those values in the macro to select records from another dataset that I'll load.

What i have in mind is something along the following lines:

keep if inlist(variable, "`macrovariable'")

Does that work? And is there another more efficient option? I could do this easily in R (because vectors are easier to work with than macros), but this project requires Stata.


Clarification:

if I have a variable with three unique values, a, b and c, I want to store those in a macro variable so I can later take another dataset and select observations that match one of those values.

Normally can use the inlist function to do this manually, but I'd like to soft-code it so I can run the program with different sets of values. And I can't get the inlist function to work with macros.

Upvotes: 2

Views: 6619

Answers (3)

Laura Paul
Laura Paul

Reputation: 1

I suspect your difficulty in using a macro generated by levelsof with inlist is that you forgot to use the separate(,) option. I also do not believe you can use the inlist function with keep if-- you will need to add the extra step of defining a new indicator.

In the example below I used the 1978 auto data and created a variable make_abb of vehicle manufacturers (or make) which took only a handful of distinct values ("Do" for Dodge, etc.).

I then used the levelsof command to generate a local macro of the manufacturers which had a vehicle model with a poor repair record (the variable rep78 is a categorical repair record variable where 1 is poor and 5 is good). The option separate(,) is what adds the commas into the macro and enables inlist to read it later on.

Finally, if I want to drop the manufacturers which did not have a poor repair record, I generate a dummy variable named "keep_me" and fill it in using the inlist function.

*load some data
sysuse auto 
*create some make categories by splitting the make and model string
gen make_abb=substr(make,1,2)
lab var make_abb "make abbreviation (string)"
*use levelsof with "local(macro_name)" and "separate(,)" options
levelsof make_abb if rep78<=2, separate(,) local(make_poor)
*generate a dummy using inlist and your levelsof macro from above
gen keep_me=1 if inlist(make_abb,`make_poor')
lab var keep_me "dummy of makes that had a bad repair record"
*now you can discard the rest of your data
keep if keep_me==1

Upvotes: 0

StasK
StasK

Reputation: 1555

* the source data
levelsof x, local( allx )
* make it -inlist-friendly
local allxcommas : subinstr local allx  " " ", ", all
* bring in the new data
use using blah.dta if inlist(x, `allxcommas')

Upvotes: 3

Richard Herron
Richard Herron

Reputation: 10102

This seems to work for me.

* "using" data
clear
tempfile so
set obs 10
foreach v in list a b c d {
    generate `v' = runiform()
}
save `so'

* "master" data
clear
set obs 10
foreach v in list e f g h {
    generate `v' = runiform()
}

* merge
local tokeepusing a b
merge 1:1 _n using `so', keepusing(`tokeepusing')

Yields:

. list

     +------------------------------------------------------------------------------------------+
     |     list          e          f          g          h          a          b        _merge |
     |------------------------------------------------------------------------------------------|
  1. | .7767971   .5910658   .6107377   .7256517    .357592   .8953723   .0871481   matched (3) |
  2. |  .643114   .6305301   .6441092   .7770287   .5247816   .4854506   .3840067   matched (3) |
  3. | .3833295    .175099   .4530386   .5267127    .628081   .2273252   .0460549   matched (3) |
  4. | .0057233   .1090542   .1437526   .3133509    .604553   .9375801   .8091199   matched (3) |
  5. | .8772233   .6420991   .5403687   .1591801   .5742173   .8948932   .4121684   matched (3) |
     |------------------------------------------------------------------------------------------|
  6. | .6526399   .5137199    .933116   .5415702   .4313532   .8602547   .5049801   matched (3) |
  7. | .2033027   .8745837      .8609   .0087578   .9844069   .1909852   .3695011   matched (3) |
  8. | .6363281   .0064866   .6632325    .307236   .9544498   .6267227   .2908498   matched (3) |
  9. |  .366027   .4896181   .0955155   .4972361   .9161932   .7391482    .414847   matched (3) |
 10. | .8637221   .8478178   .5457179   .8971257   .9640535    .541567   .1966634   matched (3) |
     +------------------------------------------------------------------------------------------+

Does this answer your question? If not, please comment.

Upvotes: -1

Related Questions