【问题标题】:Keep a list of variables when some variables don't exist当某些变量不存在时保留变量列表
【发布时间】:2018-05-14 11:53:08
【问题描述】:

对于多个国家/地区,我有一个数据集,我想为每个国家/地区保留一个变量列表(在全局 vlist 中指定)。有些变量在某些国家不存在。

我希望 Stata 忽略这些变量的不存在并对其余变量执行 keep 命令。但是,问题在于国家一级的额外 for 循环,我正在努力整合。

这个问题类似于这些线程中提出的问题:

最终,我想为每个国家/地区提供一个数据集,该数据集仅包含vlist 中指定的变量(减去vlist 中不存在的变量)。

代码如下,大部分取自上面的线程:

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 

}

但是,这会产生以下错误:

rc not found
r(111);

我希望这足以描述我的问题,但如果需要更多解释,请告诉我。

【问题讨论】:

    标签: loops stata capture stata-macros


    【解决方案1】:

    您的代码的主要问题是您没有调用每个数据集来相应地修改它。

    以下内容应该可以满足您的需求:

    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 
    }
    

    请注意,在capture 之后您需要输入!_rc不是 !rc

    【讨论】:

    • 真的不需要对变量名进行循环。这种技术通常非常有用,但在这里它会导致间接解决方案。
    【解决方案2】:

    这是一个寻找各种名称列表交集的练习。

    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 
    } 
    

    请注意,绝对不需要循环名称。

    【讨论】:

    • 这个解决方案一开始可能看起来违反直觉,但它等同于上面的解决方案。不同之处在于内部循环被宏列表操作所取代。请参阅here 了解更多信息。
    • 感谢您的加分,但这里的 counter-intuitive 是什么,例如令人费解还是倒退?语法对读者来说可能很新颖,但它是“我需要从所需的列表中识别实际存在的变量”的实现
    • 您提出的语法没有问题。如果有的话,它更干净。但我认为初学者发现循环比宏列表操作更容易思考。我以前见过几次。
    • 我明白了。这很可能是,这取决于他们以前的编程经验。我经常看到人们在观察中编写不必要的循环。
    猜你喜欢
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多