如何在 Stata 中添加一个用每个新 ID 重置的计数器
How do I add a counter in Stata that resets with each new ID
我想在我的 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
我知道这在大多数语言中都超级简单,但是这个:
if ID == ID[_n+1]{
new_var-count-year = new_var-count-year+1
}
else ...
这里好像不行。
有效的(非常糟糕的代码!)是:
gen freq_year = 1
bysort ID (year) : gen new_var-count-year = sum(freq_year)
我发现你的代码很难详细理解(x
是给定的 ID
的值,但也是要生成的变量???)但是
bysort ID : gen wanted = _n
听起来像你想要的。通常有一些变量,例如时间或时间顺序作为排序的理由。如果是这样,你应该用
拼写出来
bysort ID (time) : gen wanted = _n
如果这不是答案,您可能会发现使用虚假数据和您想要的具体示例更有可能获得解决方案。
2020 年 11 月 27 日添加到问题中的额外 material 编辑:
if
作为一个独立的语句,在给定变量名时总是在第一个观察中查找(除非其他任何内容是明确的)。对此进行了解释——尽管在我看来是倒退的,因为那里提出的问题是更常见问题的答案,为什么 if
语句不像我预期的那样工作? -- 在 this FAQ.
考虑样本数据集的这个(更正后的)版本并使用它进行一些实验。我使用 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
实验 1:在第一次观察数据集时评估变量名称引用。
. di ID
1
(对于这个示例数据集,1 是不明确的输出,但其他实验将证实这一点。)
实验 2:出于同样的原因,对 _n
的引用在相同的上下文中总是被解释为 1。 (详细信息:_n
本身意味着要显示“新行”,因此观察数解释需要括号。)
. di (_n)
1
实验 3:对 _n+1
的引用在同一上下文中始终被解释为 2。
. di (_n+1)
2
断言:即使在循环中,此类表达式的工作方式也不会受到影响。
另请注意,“在这里似乎不起作用”是不准确的:给出的代码是非法的,因为没有提供 generate
。
更积极地说,这可行,而且可能更接近您的想法。
gen wanted = 1 if ID != ID[_n-1]
replace wanted = wanted[_n-1] + 1 if missing(wanted)
总有明确循环观察的余地;它只是不是很 Stataish 或高效。它是刚刚给出的两行的慢速版本。
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'
}
对于上下文,请注意对 varname[0]
的引用始终被评估为缺失。
我想在我的 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
我知道这在大多数语言中都超级简单,但是这个:
if ID == ID[_n+1]{
new_var-count-year = new_var-count-year+1
}
else ...
这里好像不行。
有效的(非常糟糕的代码!)是:
gen freq_year = 1
bysort ID (year) : gen new_var-count-year = sum(freq_year)
我发现你的代码很难详细理解(x
是给定的 ID
的值,但也是要生成的变量???)但是
bysort ID : gen wanted = _n
听起来像你想要的。通常有一些变量,例如时间或时间顺序作为排序的理由。如果是这样,你应该用
拼写出来bysort ID (time) : gen wanted = _n
如果这不是答案,您可能会发现使用虚假数据和您想要的具体示例更有可能获得解决方案。
2020 年 11 月 27 日添加到问题中的额外 material 编辑:
if
作为一个独立的语句,在给定变量名时总是在第一个观察中查找(除非其他任何内容是明确的)。对此进行了解释——尽管在我看来是倒退的,因为那里提出的问题是更常见问题的答案,为什么 if
语句不像我预期的那样工作? -- 在 this FAQ.
考虑样本数据集的这个(更正后的)版本并使用它进行一些实验。我使用 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
实验 1:在第一次观察数据集时评估变量名称引用。
. di ID
1
(对于这个示例数据集,1 是不明确的输出,但其他实验将证实这一点。)
实验 2:出于同样的原因,对 _n
的引用在相同的上下文中总是被解释为 1。 (详细信息:_n
本身意味着要显示“新行”,因此观察数解释需要括号。)
. di (_n)
1
实验 3:对 _n+1
的引用在同一上下文中始终被解释为 2。
. di (_n+1)
2
断言:即使在循环中,此类表达式的工作方式也不会受到影响。
另请注意,“在这里似乎不起作用”是不准确的:给出的代码是非法的,因为没有提供 generate
。
更积极地说,这可行,而且可能更接近您的想法。
gen wanted = 1 if ID != ID[_n-1]
replace wanted = wanted[_n-1] + 1 if missing(wanted)
总有明确循环观察的余地;它只是不是很 Stataish 或高效。它是刚刚给出的两行的慢速版本。
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'
}
对于上下文,请注意对 varname[0]
的引用始终被评估为缺失。