0

For several countries, I have one dataset and I want to keep a list of variables (specified in a global vlist) for each of them. Some variables do not exist in some countries.

I want Stata to ignore the non-existence of these variables and execute the keep command for the rest of the variables. However, the problem is the additional for loop on the country-level, that I'm struggling to incorporate.

This question is similar to the one asked in these threads:

Ultimately, I want to end up with a dataset for each country that has only those variables specified in the vlist (minus the ones from the vlist that do not exist).

Here's the code, which is mostly taken from the thread above:

clear all
set obs 5

local vlist v0 v1 v2 v3 v4 v5

foreach v of local vlist { 
    generate `v' = runiform()
}

save country1.DTA, replace
save country2.DTA, replace
save country3.DTA, replace

global vlist_example v0 v1 v6          // v6 is not part of the dataset

foreach country in country1 country2 country3 {
   local keeplist = ""
      foreach i of global vlist_example {
          capture confirm variable `i'
              if !rc {
                  local "`keeplist' `i'"
          }
      }
keep `keeplist'     
save `country'beta2.DTA, replace 

}

However, this produces the following error:

rc not found
r(111);

I hope this sufficiently describes my problem, but please let me know if anything needs more explaining.

Timo K
  • 29
  • 6

2 Answers2

1

The main problem with your code is that you do not call each dataset to modify it accordingly.

The following should give you what you want:

clear all
set obs 5

local vlist v0 v1 v2 v3 v4 v5

foreach v of local vlist { 
    generate `v' = runiform()
}

save country1, replace
save country2, replace
save country3, replace

global vlist_example v0 v1 v6          // v6 is not part of the dataset

foreach country in country1 country2 country3 {
    use `country'.dta, clear
    local keeplist ""
    foreach i of global vlist_example {
        capture confirm variable `i'
        if !_rc {
            local keeplist "`keeplist' `i'"
        }
    }
    keep `keeplist'     
    save `country'beta2, replace 
}

Note that after capture you need to type !_rc and not !rc.

  • A loop over variable names really isn't needed. This technique is often extremely useful, but here it leads to an indirect solution. – Nick Cox May 14 '18 at 13:51
0

That's an exercise in finding the intersections of various lists of names.

local wanted v0 v1 v6    

foreach set in country1 country2 country3 { 
   use `set', clear 
   describe, varlist 
   local this `r(varlist)' 
   local exist : list wanted & this 
   keep `exist'
   * save command here 
} 

Note that looping over names is absolutely not needed.

Nick Cox
  • 35,529
  • 6
  • 31
  • 47
  • This solution may appear counter-intuitive at first but it is equivalent to the one above. The difference is that the inner loop is substituted with macro list manipulation. See [here](https://www.stata.com/manuals/pmacrolists.pdf) for more information. –  May 14 '18 at 14:31
  • Thanks for the plus, but what is _counter-intuitive_ here, e.g. puzzling or backwards? The syntax may be novel to a reader, but it's an implementation of "I need to identify the variables that actually exist from a list of those wanted" – Nick Cox May 14 '18 at 14:56
  • There is nothing wrong with the syntax you propose. If anything, it is more clean. But i think beginners find it easier to think in terms of loops than macro list manipulations. I have seen this several times before. –  May 14 '18 at 15:02
  • I see. That could well be, depending on their previous programming experience. I often see people programming unnecessary loops over observations. – Nick Cox May 14 '18 at 15:09