2
votes

I have a set of 18 Stata data files (one per year) whose names are:

{aindresp.dta, bindresp.dta, ... , rindresp.dta}

I want to eliminate some variables from each dataset. For this, I want to use the fact that many variables across dataset have the same name, plus a prefix given by the dataset prefix (a, b, c, ... r). For example, the variable rach12 is called arach12 in dataset aindresp.dta, etc. Thus, to clean each dataset, I run a loop like the following:

clear all
local list a b c d e f g h i j k l m n o p q r
foreach var of local list {
use `var'indresp.dta
drop `var'rach12 `var'jbchc1 `var'jbchc2 `var'jbchc3 `var'xpchcf var'xpchc
save `var'indresp.dta, replace
}

The actual loop is much larger. I am deleting around 200 variables.

The problem is that some variables change name over time, or disappear after a few years. Other variables are added. Therefore, the loop stops as soon as a variable is not found. This is because the drop command in Stata stops. Yet, that command has no option to force it to continue.

How can I achieve my goal? I would not like to go manually over each dataset.

1

1 Answers

4
votes

help capture

You can just put capture in front of the drop. You can just keep going, but a little better would be to flag which datasets fail.

In this sample code, I've presumed that there is no point to the save, replace if you didn't drop anything. The basic idea is that a failure of a command results in a non-zero error code accessible in _rc. This will be positive (true) if there was a failure and zero (false) otherwise.

A more elaborate procedure would be to loop over the variables concerned and flag specific variables not found.

clear all
local list a b c d e f g h i j k l m n o p q r
foreach var of local list {
    use `var'indresp.dta
    capture drop `var'rach12 `var'jbchc1 `var'jbchc2 `var'jbchc3 `var'xpchcf var'xpchc
    if _rc { 
        noisily di "Note: failure for `var'indresp.data" 
    } 
    else save `var'indresp.dta, replace
}

See also Does Stata have any `try and catch` mechanism similar to Java?

EDIT:

If you want to drop whatever exists, then this should suffice for your problem.

clear all
local list a b c d e f g h i j k l m n o p q r
foreach var of local list {

    use `var'indresp.dta
    capture drop `var'rach12 `var'jbchc1 `var'jbchc2 `var'jbchc3 `var'xpchcf var'xpchc
    if _rc { 
        di "Note: problem for `var'indresp.data" 
        checkdrop `var'rach12 `var'jbchc1 `var'jbchc2 `var'jbchc3   
    } 

    save `var'indresp.dta, replace
}

where checkdrop is something like

*! 1.0.0 NJC 1 April 2016 
program checkdrop
    version 8.2 

    foreach v of local 0 { 
        capture confirm var `v' 
        if _rc == 0 { 
            local droplist `droplist' `v'  
        } 
        else local badlist `badlist' `v'  
    } 

    if "`badlist'" != "" {
        di _n "{p}{txt}variables not found: {res}`badlist'{p_end}" 
    } 

    if "`droplist'" != "" { 
        drop `droplist' 
    } 
end