如果至少一个单元格符合给定标准(例如,有缺失值),则删除所有 id 行

Dropping all id rows if at least one cell meets a given criterion (e.g. has a missing value)

我的数据集采用以下形式:

clear

input   id  var

            1   20      
            1   21      
            1   32      
            1   34     
            2   11     
            2   .     
            2   15     
            3   21     
            3   22    
            3   1     
            3   2
            3   5
end

在我的真实数据集中,观察结果按 idyear 排序(此处未显示)。

如果(至少)满足以下两个条件之一,我需要做的是删除 所有 特定 id 的行:

  1. var至少有一个缺失值。
  2. var 从一行减少到下一行(对于相同的 id

所以在我的例子中我想得到的是:

       id  var

        1   20      
        1   21      
        1   32      
        1   34     

现在,我不幸的尝试是将行操作与 by 一起使用,以创建一个 drop1 变量,稍后用于对数据集进行子集化。 这些线路上的东西(这显然是错误的):

bysort id: gen drop1=1 if var[_n] < var[_n-1] | var[_n]==.

这行不通,我什至不确定我正在考虑最"clean"最直接的方式来解决任务。

您将如何进行?任何帮助将不胜感激。

我的解释是,如果满足两个条件中的任何一个,您希望删除整个组。我假设您的数据集以某种方式排序,很可能是基于另一个变量。否则结构脆弱

逻辑很简单。检查递减值但忽略每组的第一个观察值,即忽略 _n == 1。如果没有缺失,第一个观察值将始终较小。然后,还要检查是否有遗漏。

clear
set more off

input   id  var
            1   20      
            1   21      
            1   32      
            1   34     
            2   11     
            2   .     
            2   15     
            3   21     
            3   22    
            3   1     
            3   2
            3   5
end

// maintain original sequencing
gen orig = _n
order id orig

bysort id (orig) : gen todrop = sum((var < var[_n-1] & _n > 1) | missing(var))
list, sepby(id)

by id : drop if todrop[_N]
list, sepby(id)

一种方法是像您尝试的那样创建一些指标变量。如果您只想将 var 从一个观察值减少到下一个观察值,您可以使用:

clear
input   id  var
        1   20      
        1   21      
        1   32      
        1   34     
        2   11     
        2   .     
        2   15     
        3   21     
        3   22    
        3   1     
        3   2
        3   5
        4   .
        4   2
 end

gen i = id if mi(var)
bysort id : egen k = mean(i)

drop if id == k

drop i k

drop if var[_n-1] > var[_n] & _n != 1

但是,如果你想获得你在 post 中提供的输出(删除所有 var 从某个最大值减少的后续观察),你可以尝试以下代替上面的最后一行。

local N = _N

forvalues i = 1/`N' {
    drop if var[_n-1] > var[_n] & _n != 1
}

循环只是确保代码的 drop if var... 部分被充分执行,以便丢弃 var < 34 处的所有观察结果。