如果至少一个单元格符合给定标准(例如,有缺失值),则删除所有 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
在我的真实数据集中,观察结果按 id
和 year
排序(此处未显示)。
如果(至少)满足以下两个条件之一,我需要做的是删除 所有 特定 id
的行:
var
至少有一个缺失值。
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
处的所有观察结果。
我的数据集采用以下形式:
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
在我的真实数据集中,观察结果按 id
和 year
排序(此处未显示)。
如果(至少)满足以下两个条件之一,我需要做的是删除 所有 特定 id
的行:
var
至少有一个缺失值。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
处的所有观察结果。