【问题标题】:Make Stata command "drop" to continue even if variable not found即使找不到变量,也使Stata命令“drop”继续
【发布时间】:2016-04-01 09:21:25
【问题描述】:

我有一组 18 个 Stata 数据文件(每年一个),它们的名称是:

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

我想从每个数据集中消除一些变量。为此,我想利用数据集中的许多变量具有相同名称的事实,加上数据集前缀 (a, b, c, ... r) 给出的前缀。例如,变量rach12 在数据集aindresp.dta 中被称为arach12 等。因此,为了清理每个数据集,我运行如下循环:

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
}

实际的循环要大得多。我正在删除大约 200 个变量。

问题是一些变量会随着时间的推移而改变名称,或者在几年后消失。添加其他变量。因此,一旦找不到变量,循环就会停止。这是因为 Stata 中的drop 命令停止了。然而,该命令无法强制它继续执行。

我怎样才能实现我的目标?我不想手动检查每个数据集。

【问题讨论】:

    标签: loops foreach stata


    【解决方案1】:

    help capture

    您可以将capture 放在drop 前面。您可以继续前进,但更好的做法是标记哪些数据集失败。

    在这个示例代码中,我假设如果你没有 drop 任何东西,save, replace 就没有意义。基本思想是命令失败会导致在_rc 中可访问的非零错误代码。如果发生故障,这将是肯定的(真),否则为零(假)。

    更复杂的过程是循环相关变量并标记未找到的特定变量。

    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
    }
    

    另见Does Stata have any `try and catch` mechanism similar to Java?

    编辑:

    如果您想drop 任何存在,那么这应该足以解决您的问题。

    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
    }
    

    checkdrop 类似于

    *! 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 
    

    【讨论】:

    • 嗯,如果命令失败,使用capture 会继续迭代(作为帖子的标题)。和我之前的标题一样,我的目标是让drop 命令继续删除,即使没有找到一个变量。或者,我必须按照您的建议为每个单个变量写一个 drop。是否没有用户编写的命令可以在命令行中删除所有找到的变量?
    • 我没有在你的问题中看到如果出现问题你想做什么。标题只是“继续循环”。但如果答案是“drop 任何存在”,那么这是一个简单的程序。我将在上面进行编辑。
    • 太好了!我对Stata代码不是很了解,但是您的程序是否在每个循环中临时删除变量?
    • 一点也不。除了再次读回数据集之外,Stata 中没有这样的事情吗?你想drop变量吗?没有中间道路。
    • 我的意思是如果上面的代码将检查相同的原始变量子集以删除每次迭代。假设要删除的变量是a c d e f g。如果b 不在第一次迭代数据集中,那么第二次迭代是否也会查找b?这就是我对每个循环中的临时子集的意思。也许我不理解你的代码。它不是在 drop 命令中查找相应迭代数据集中存在的所有变量并将其保存为droplist
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多