有没有办法只保留列表中的变量,而忽略数据集中不存在的列出变量?

Is there a way to keep only variables from a list, while ignoring listed variables that are not present in the dataset?

我有几个不同的数据集,对于每个数据集,我只需要保留一个变量列表。然而,当我 运行 一个简单的 keep 命令时,我最终得到一个错误,因为并非我提供的列表中的所有变量都存在于每个数据集中。有没有一种简单的方法可以解决这个问题,比如说,我缺少 keep 的选项?如果没有,有没有一种方法可以让每个数据集都可以将 keep 中的 varlist 定义为仅来自当前数据集中存在的主列表中的那些?

谢谢大家。我刚开始使用 Stata(以前是 R),所以有时我仍然停留在 R 的看待事物的方式上。如果有任何提示,我将不胜感激。

我建议结合使用 describe 和一些扩展的宏函数。假设您有两个要比较的 .dta 文件,set1 和 set2。

然后您可以按照以下方式做一些事情:

describe set1, varlist
local set1vars `r(varlist)'

describe set2, varlist
local set2vars `r(varlist)'

local both : list set1vars & set2vars

这将创建一个本地宏,both,其中包含一个字符串,其中包含两个数据集中都存在的变量名称。在 keep 命令中使用此宏,仅 keep 存在于两个集合中的变量。

一个更详尽的示例如下所示:

local keeplist "make mpg foreign price"

/* Describe auto dataset */
describe using "C:/Program Files (x86)/Stata13/ado/base/a/auto.dta", varlist
local setlist1 `r(varlist)'

local keep : list keeplist & setlist1

tempfile auto
use `keep' using "C:/Program Files (x86)/Stata13/ado/base/a/auto.dta"
save `auto'

describe using "C:/Program Files (x86)/Stata13/ado/base/a/autornd.dta", varlist
local setlist2

local keep : list keeplist & setlist2

use `keep' using "C:/Program Files (x86)/Stata13/ado/base/a/autornd.dta", clear

/* Do whatever you want with now similar datasets */
* i.e., 
merge 1:1 make using `auto'

请注意,在上面的示例中,您可以对数据发出 describe 而无需将其读入内存。按照这个逻辑,很容易将其合并到一个循环中,正如@Brendan Cox 所说明的那样。

其他选项涉及 unabcfvars(可从 ssc 获得)。

有关该主题的更多讨论,请参阅类似问题

扩展 ander2ed 的答案,您可以定义要保留的 "master list" 个变量,然后只保留来自不同数据集的匹配变量——例如:

local keepvars = "make weight mpg length"

sysuse auto, clear // contains the four variables above (and others)
qui ds 
local dsvars `r(varlist)'
local keeplist : list keepvars & dsvars
di "`keeplist'"
keep `keeplist'

sysuse autornd, clear // contains only make, weight, & mpg
qui ds 
local dsvars `r(varlist)'
local keeplist : list keepvars & dsvars
di "`keeplist'"
keep `keeplist'

如果需要,这可以很容易地变成一个循环:

// loop approach
local keepvars = "make weight mpg length"
local dslist = "auto autornd"
foreach ds of local dslist {
    qui sysuse `ds', clear
    qui ds
    local dsvars `r(varlist)'
    local keeplist : list keepvars & dsvars
    keep `keeplist'
    di as input ">>> `ds'"
    ds
    // save
}

与 Brendan 的回答类似,您可以使用 foreach 循环来创建局部变量。您可以使用命令 isvar,但我更喜欢只使用 capture des 并依赖于 return 代码。对于下面的示例,假设我们有兴趣保留的所有变量都是 "a,b,c,d"

    forval n = 1/2{
      use data_set_`n', clear
      foreach potential_var in a b c d{
        capture qui des `a'
        if _rc == 0{
          local keep_list "`keep_list'" `a'
        }
      }
      keep `keep_list'
      save data_set_`n'_kept, replace
    }