我的表格如下:
ID AQ_ATC amountATC
. "A05" 1
123 "A05AA02" 2525
234 "A05AA02" 2525
991 "A05AD39" 190
. "C10" 1
441 "C10AA11" 4330
229 "C10AA22" 3100
. "C05AA" 1
441 "C05AA03" 130
完整的8个字符AQ_ATC
代码的计数已经正确。
较短的代码在表中是唯一的,并且是完整的8字符代码的子字符串(它们代表前x个字符)。
我要找的是整个表中较短代码的出现次数。
例如,在这种情况下,结果表将是
ID AQ_ATC amountATC
. "A05" 2715 <-- 2525 + 190
123 "A05AA02" 2525
234 "A05AA02" 2525
991 "A05AD39" 190
. "C10" 7430 <-- 4330 + 3100
441 "C10AA11" 4330
229 "C10AA22" 3100
. "C05AA" 130 <-- 130
441 "C05AA03" 130
部分代码不重叠,我的意思是,如果有"C05"
则不会有另一部分代码"C05A1
&#34;。
我使用
创建了amountATC列bysort ATC: egen amountATC = total(AQ_ATC==AQ_ATC)
我试图回收昨天收到的代码,但未能这样做。 我的尝试看起来像这样:
levelsof AQ_ATC, local(ATCvals)
quietly foreach y in AQ_ATC {
local i = 0
quietly foreach x of local ATCvals {
if strpos(`y', `"`x'"') == 1{
local i = `i'+1
replace amountATC = `i'
}
}
}
我的想法是使用一个柜台&#34;我&#34;每当AQ_ATC
以另一个AQ_ATC
代码开头时,将其增加1。然后我写了#34;我&#34;进入amountATC
并且在我遍历我的AQ_ATC
的整个表之后,我将得到一个&#34; i&#34; - 值将等于子字符串的出现量。然后我重置&#34;我&#34;为0并继续下一个AQ_ATC
。
至少这就是我打算如何工作,它最终做的是将所有amountATC
- 值设置为1.
我还试图研究不同的egen函数,例如noccur和moss,但是当我尝试安装软件包时,我的连接会保持超时。
答案 0 :(得分:4)
好像你来自另一种语言而且你坚持使用循环时并非严格必要。 Stata在没有显式循环的情况下做很多事情,正是因为命令已经适用于所有观察。
一种方法是:
clear
set more off
input ///
ID str15 AQ_ATC amountATC
. "A05" 1
123 "A05AA02" 2525
234 "A05AA02" 2525
991 "A05AD39" 190
. "C10" 1
441 "C10AA11" 4330
229 "C10AA22" 3100
. "C05AA" 1
441 "C05AA03" 130
end
*----- what you want -----
sort AQ_ATC ID
gen grou = sum(missing(ID))
bysort grou AQ_ATC: gen tosum = amountATC if _n == 1 & !missing(ID)
by grou: egen s = total(tosum)
replace amountATC = s if missing(ID)
list, sepby(grou)
通过编辑,适用相同的原则。下面的代码会根据您的更改进行调整并略微更改代码(少一行):
*----- what you want -----
sort AQ_ATC
gen grou = sum(missing(ID))
bysort grou: gen s = sum(amountATC) if AQ_ATC != AQ_ATC[_n+1] & !missing(ID)
by grou: replace amountATC = s[_N] if missing(ID)
效率应该更高:
<snip>
bysort grou: gen s = sum(amountATC) if AQ_ATC != AQ_ATC[_n+1]
by grou: replace amountATC = s[_N] - 1 if missing(ID)
一些意见:
sort
是一个非常方便的命令。如果按AQ_ATC
对数据进行排序,则它们的排列方式使得短(子)字符串放在相应的长字符串之前。
by:
前缀是基本的,非常有用,我注意到您可以在定义适当的组后使用它。我利用所有短(子)字符串都有missing(ID)
的事实创建了这些组。
然后(由刚刚定义的组)您只想为每amountATC
添加一个值(观察)。这就是条件if AQ_ATC != AQ_ATC[_n+1]
的作用。
最后,replace
返回原始变量。我通常会generate
复制并使用它,因此我的原始变量不会受到影响。
Nick Cox对by:
前缀的优秀读物为Speaking Stata: How to move step by: step。
另一种略有不同的方式:
*----- what you want -----
sort AQ_ATC
gen grou = sum(missing(ID))
egen t = tag(grou AQ_ATC)
bysort grou: gen s = sum(amountATC * t)
by grou: replace amountATC = s[_N] - 1 if missing(ID)