我想在我的 Stata 数据集中添加一个计数器(new_var-count-year)。
ID year new_var-count-year
1 2000 1
1 2001 2
1 2002 2
2 2001 1
2 2002 2
3 1999 1
3 2000 2
3 2001 3
3 2002 4
4 2005 1
5 2000 1
5 2001 2
Run Code Online (Sandbox Code Playgroud)
我知道这在大多数语言中都非常简单,但是:
if ID == ID[_n+1]{
new_var-count-year = new_var-count-year+1
}
else ...
Run Code Online (Sandbox Code Playgroud)
似乎在这里不起作用。
什么工作(非常糟糕的代码!)是:
gen freq_year = 1
bysort ID (year) : gen new_var-count-year = sum(freq_year)
Run Code Online (Sandbox Code Playgroud)
我找到你的代码硬详细跟随(x是一个值的ID被给予,而且一个变量来产生???)但
bysort ID : gen wanted = _n
Run Code Online (Sandbox Code Playgroud)
听起来像你所要求的。通常有一些变量,例如时间或时间顺序作为排序的基本原理。如果是这样,你应该用
bysort ID (time) : gen wanted = _n
Run Code Online (Sandbox Code Playgroud)
如果这不是答案,您可能会发现使用虚假数据和您想要的特定示例更有可能获得解决方案。
编辑添加到问题 2020 年 11 月 27 日的额外材料:
if作为一个独立的语句,当给定变量名称时,它总是在第一个观察中查找(除非其他任何内容都是明确的)。这得到了解释 - 尽管在我看来是倒退的,因为那里提出的问题是对更常见的问题的答案,为什么if语句不能按我的预期工作?- 在此常见问题解答中。
考虑一下您的示例数据集的这个(更正)版本和一些实验。我使用display(di被接受为缩写)。
clear
input ID year new_var_count_year
1 2000 1
1 2001 2
1 2002 2
2 2001 1
2 2002 2
3 1999 1
3 2000 2
3 2001 3
3 2002 4
4 2005 1
5 2000 1
5 2001 2
end
Run Code Online (Sandbox Code Playgroud)
实验 1:在数据集的第一次观察中评估变量名称引用。
. di ID
1
Run Code Online (Sandbox Code Playgroud)
(对于这个示例数据集,1 是不明确的输出,但其他实验将证实这一点。)
实验 2:出于同样的原因_n,在相同的上下文中,对的引用总是被解释为 1。(详细信息:_n本身意味着要显示“新行”,因此观察号解释需要括号。)
. di (_n)
1
Run Code Online (Sandbox Code Playgroud)
实验 3:_n+1在相同的上下文中,对的引用总是被解释为 2。
. di (_n+1)
2
Run Code Online (Sandbox Code Playgroud)
断言:即使在循环中,此类表达式的工作方式也不受影响。
另请注意,“似乎在这里不起作用”是不精确的:给出的代码是非法的,因为没有generate提供。
更积极的是,这很有效,并且可能更接近您的想法。
gen wanted = 1 if ID != ID[_n-1]
replace wanted = wanted[_n-1] + 1 if missing(wanted)
Run Code Online (Sandbox Code Playgroud)
始终存在对观察进行显式循环的余地;它只是不太稳定或高效。它是刚刚给出的两行的慢速版本。
gen wanted = .
local n = _N
forval i = 1/`n' {
if id[`i'] != id[`i' - 1] replace wanted = 1 in `i'
else replace wanted = wanted[`i' - 1] + 1 in `i'
}
Run Code Online (Sandbox Code Playgroud)
对于上下文,请注意对varname的引用[0]始终被评估为缺失。