Reputation: 565
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
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
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
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