4

I have 100 dta files. I have a list of variables that I need to keep and save temporary copies on the fly. Some variables may or may not exist in a certain dta.

I need Stata to keep all variables that exist in a dta and ignore those that do not exist.

The following code has wrong syntax, but it could serve as a good pseudo code to give one a general idea of what should be done:

forval j = 1/100 {
    use data`j'
    local myVarList =""

    foreach i of varlist  var1 var2 var3 var4 var5 var6 var7 var8  {
        capture sum `i'
        if _rc = 0 {
            `myVarList' = `myVarList'" "`i'
        }
    }

    keep `myVarList'
    save temporaryData`j'
}

Is there any way to do this?

CHEBURASHKA
  • 1,623
  • 11
  • 53
  • 85

1 Answers1

7

There are many issues with your code. Here's one way to do the inner loop.

/* one fake dataset */
set obs 5
gen var1 = 1
gen var2 = 2
gen var3 = "c"
gen z    = 35

ds

/* keep part */
local masterlist "var1 var2"
local keeplist = ""

foreach i of local masterlist  {
    capture confirm variable `i'
        if !_rc {
            local keeplist "`keeplist' `i'"
        }
}

keep `keeplist'

The key part is that you can't foreach i of varlist phantomvar, since Stata will check the existence and error out. Similarly, putting the local name in special quotes will evaluate it, but you're trying to redefine. You may find set trace on a useful feature in debugging.

This is somewhat better code:

unab allvars: _all
local masterlist "var1 var2 phantomvar"
local keeplist: list allvars & masterlist
keep `keeplist'
dimitriy
  • 9,077
  • 2
  • 25
  • 50
  • Thank you for answer. However, it does not work if the `masterlist` was: `local masterlist "var1 someNonexistingVar var2"`. My `.dta` files do not necessarily have all variables. – CHEBURASHKA Jun 12 '13 at 02:03
  • Good catch. "Existence" should have been "variable". Fixed now. – dimitriy Jun 12 '13 at 02:09
  • Thank you. That works!!! May i ask about the `"This is somewhat better code:"` part... Where do i use it? – CHEBURASHKA Jun 12 '13 at 02:11
  • Replace everything under the /*keep part*/ with it. – dimitriy Jun 12 '13 at 02:13
  • The third line finds the intersection of the masterlist variables and the variables in the current data set and stores them in a local macro named keeplist. You will still need to loop over the data sets and save the new files. – dimitriy Jun 12 '13 at 02:16
  • For the record, in terms of the original code: "didn't work" can mean anything from "does not do what I want" to "is illegal"; here it's the latter. The line `\`myVarList' = \`myVarList'" "\`i'` contains several mistakes, starting with the lack of an initial `local`. – Nick Cox Jun 12 '13 at 06:34
  • @DimitriyV.Masterov i like the `better solution`. it is awesome. but i am confused about `local keeplist: list allvars & masterlist`. This line seems to work even without this part: `: list allvars &`... Why do i need to `unab` and then to join `&` it with `masterlist`? Thank you~ – CHEBURASHKA Jun 12 '13 at 17:56
  • I don't think it should work. I certainly does not with my toy example. Start another question with some actual code. – dimitriy Jun 12 '13 at 18:12
  • `local keeplist` is perfectly legal. It just blanks out any existing local macro with the name `keeplist`, which on occasion is what you want. – Nick Cox Jun 12 '13 at 22:04