foreach 命令宏中的多个本地
Multiple local in foreach command macro
我有一个包含多个子组(变量 economist
)和日期(变量 temps99
)的数据集。
我想运行一个不接受bysort
或by
前缀的tabsplit
命令。所以我创建了一个宏来将我的 tabsplit
命令应用于我数据中的每个子组。
例如:
levelsof economist, local(liste)
foreach gars of local liste {
display "`gars'"
tabsplit SubjectCategory if economist=="`gars'", p(;) sort
return list
replace nbcateco = r(r) if economist == "`gars'"
}
对于每个子组,Stata 运行s tabsplit
命令,我使用变量 nbcateco
来存储计数结果。
我对日期做了同样的事情,所以我可以随着时间的推移得到 r(r)
的演变:
levelsof temps99, local(liste23)
foreach time of local liste23 {
display "`time'"
tabsplit SubjectCategory if temps99 == "`time'", p(;) sort
return list
replace nbcattime = r(r) if temps99 == "`time'"
}
现在我想按日期 temps99
在每个子组 economist
上执行此操作。我尝试了多种组合,但我对宏不是很好(还没有?)。
我想要的是能够随着时间的推移为我的每个子组拥有我的 r(r)
。
我认为这是 XY 问题的一个例子。参见 http://xyproblem.info/
tabsplit
是来自 SSC 的包 tab_chi
中的命令。正如我写的那样,我对此没有任何负面情绪,但在这里似乎完全没有必要。
您想计算字符串变量中的类别:分号是您的分隔符。所以计算分号并加 1。
local SC SubjectCategory
gen NCategory = 1 + length(`SC') - length(subinstr(`SC', ";", "", .))
然后(例如)table
或 tabstat
将让您按兴趣组进一步探索。
要查看计数思路,请考虑 3 个类别和 2 个分号。
. display length("frog;toad;newt")
14
. display length(subinstr("frog;toad;newt", ";", "", .))
12
如果我们用空字符串替换每个分号,长度的变化就是删除的分号数。请注意,我们不必更改变量即可执行此操作。然后加 1。另见 this paper。
也就是说,扩展您的方法的方法可能是
egen class = group(economist temps99), label
su class, meanonly
local nclass = r(N)
gen result = .
forval i = 1/`nclass' {
di "`: label (class) `i''"
tabsplit SubjectCategory if class == `i', p(;) sort
return list
replace result = r(r) if class == `i'
}
使用statsby
会更好。另见 this FAQ。
这是一个解决方案,展示了如何计算每个按组内不同出版物类别的数量。这使用 runby
(来自 SSC)。 runby
遍历每个 by-group,每次用当前 by-group 中的数据替换内存中的数据。对于每个 by-group,执行用户程序中包含的命令。当用户的程序终止时,内存中剩余的任何内容都被视为结果并累积。处理完所有组后,这些结果将替换内存中的数据。
我使用了 verbose
选项,因为我想使用漂亮的格式显示每个分组的结果。不同类别列表的推导是通过拆分每个列表、转换为长布局并减少每个不同值的一个观察来完成的。 distinct_categories
程序生成一个变量,其中包含按组的不同类别的最终计数。
* create a demontration dataset
* ------------------------------------------------------------------------------
clear all
set seed 12345
* Example generated by -dataex-. To install: ssc install dataex
clear
input str19 economist
"Carmen M. Reinhart"
"Janet Currie"
"Asli Demirguc-Kunt"
"Esther Duflo"
"Marianne Bertrand"
"Claudia Goldin"
"Bronwyn Hughes Hall"
"Serena Ng"
"Anne Case"
"Valerie Ann Ramey"
end
expand 20
bysort economist: gen temps99 = 1998 + _n
gen pubs = runiformint(1,10)
expand pubs
sort economist temps99
gen pubid = _n
local nep NEP-AGR NEP-CBA NEP-COM NEP-DEV NEP-DGE NEP-ECM NEP-EEC NEP-ENE ///
NEP-ENV NEP-HIS NEP-INO NEP-INT NEP-LAB NEP-MAC NEP-MIC NEP-MON ///
NEP-PBE NEP-TRA NEP-URE
gen SubjectCategory = ""
forvalues i=1/19 {
replace SubjectCategory = SubjectCategory + " " + word("`nep'",`i') ///
if runiform() < .1
}
replace SubjectCategory = subinstr(trim(SubjectCategory)," ",";",.)
leftalign // from SSC
* ------------------------------------------------------------------------------
program distinct_categories
dis _n _n _dup(80) "-"
dis as txt "fille = " as res economist[1] as txt _col(68) " temps = " as res temps99[1]
// if there are no subjects for the group, exit now to avoid a no obs error
qui count if !mi(trim(SubjectCategory))
if r(N) == 0 exit
// split categories, reshape to a long layout, and reduce to unique values
preserve
keep pubid SubjectCategory
quietly {
split SubjectCategory, parse(;) gen(cat)
reshape long cat, i(pubid)
bysort cat: keep if _n == 1
drop if mi(cat)
}
// show results and generate the wanted variable
list cat
local distinct = _N
dis _n as txt "distinct = " as res `distinct'
restore
gen wanted = `distinct'
end
runby distinct_categories, by(economist temps99) verbose
我有一个包含多个子组(变量 economist
)和日期(变量 temps99
)的数据集。
我想运行一个不接受bysort
或by
前缀的tabsplit
命令。所以我创建了一个宏来将我的 tabsplit
命令应用于我数据中的每个子组。
例如:
levelsof economist, local(liste)
foreach gars of local liste {
display "`gars'"
tabsplit SubjectCategory if economist=="`gars'", p(;) sort
return list
replace nbcateco = r(r) if economist == "`gars'"
}
对于每个子组,Stata 运行s tabsplit
命令,我使用变量 nbcateco
来存储计数结果。
我对日期做了同样的事情,所以我可以随着时间的推移得到 r(r)
的演变:
levelsof temps99, local(liste23)
foreach time of local liste23 {
display "`time'"
tabsplit SubjectCategory if temps99 == "`time'", p(;) sort
return list
replace nbcattime = r(r) if temps99 == "`time'"
}
现在我想按日期 temps99
在每个子组 economist
上执行此操作。我尝试了多种组合,但我对宏不是很好(还没有?)。
我想要的是能够随着时间的推移为我的每个子组拥有我的 r(r)
。
我认为这是 XY 问题的一个例子。参见 http://xyproblem.info/
tabsplit
是来自 SSC 的包 tab_chi
中的命令。正如我写的那样,我对此没有任何负面情绪,但在这里似乎完全没有必要。
您想计算字符串变量中的类别:分号是您的分隔符。所以计算分号并加 1。
local SC SubjectCategory
gen NCategory = 1 + length(`SC') - length(subinstr(`SC', ";", "", .))
然后(例如)table
或 tabstat
将让您按兴趣组进一步探索。
要查看计数思路,请考虑 3 个类别和 2 个分号。
. display length("frog;toad;newt")
14
. display length(subinstr("frog;toad;newt", ";", "", .))
12
如果我们用空字符串替换每个分号,长度的变化就是删除的分号数。请注意,我们不必更改变量即可执行此操作。然后加 1。另见 this paper。
也就是说,扩展您的方法的方法可能是
egen class = group(economist temps99), label
su class, meanonly
local nclass = r(N)
gen result = .
forval i = 1/`nclass' {
di "`: label (class) `i''"
tabsplit SubjectCategory if class == `i', p(;) sort
return list
replace result = r(r) if class == `i'
}
使用statsby
会更好。另见 this FAQ。
这是一个解决方案,展示了如何计算每个按组内不同出版物类别的数量。这使用 runby
(来自 SSC)。 runby
遍历每个 by-group,每次用当前 by-group 中的数据替换内存中的数据。对于每个 by-group,执行用户程序中包含的命令。当用户的程序终止时,内存中剩余的任何内容都被视为结果并累积。处理完所有组后,这些结果将替换内存中的数据。
我使用了 verbose
选项,因为我想使用漂亮的格式显示每个分组的结果。不同类别列表的推导是通过拆分每个列表、转换为长布局并减少每个不同值的一个观察来完成的。 distinct_categories
程序生成一个变量,其中包含按组的不同类别的最终计数。
* create a demontration dataset
* ------------------------------------------------------------------------------
clear all
set seed 12345
* Example generated by -dataex-. To install: ssc install dataex
clear
input str19 economist
"Carmen M. Reinhart"
"Janet Currie"
"Asli Demirguc-Kunt"
"Esther Duflo"
"Marianne Bertrand"
"Claudia Goldin"
"Bronwyn Hughes Hall"
"Serena Ng"
"Anne Case"
"Valerie Ann Ramey"
end
expand 20
bysort economist: gen temps99 = 1998 + _n
gen pubs = runiformint(1,10)
expand pubs
sort economist temps99
gen pubid = _n
local nep NEP-AGR NEP-CBA NEP-COM NEP-DEV NEP-DGE NEP-ECM NEP-EEC NEP-ENE ///
NEP-ENV NEP-HIS NEP-INO NEP-INT NEP-LAB NEP-MAC NEP-MIC NEP-MON ///
NEP-PBE NEP-TRA NEP-URE
gen SubjectCategory = ""
forvalues i=1/19 {
replace SubjectCategory = SubjectCategory + " " + word("`nep'",`i') ///
if runiform() < .1
}
replace SubjectCategory = subinstr(trim(SubjectCategory)," ",";",.)
leftalign // from SSC
* ------------------------------------------------------------------------------
program distinct_categories
dis _n _n _dup(80) "-"
dis as txt "fille = " as res economist[1] as txt _col(68) " temps = " as res temps99[1]
// if there are no subjects for the group, exit now to avoid a no obs error
qui count if !mi(trim(SubjectCategory))
if r(N) == 0 exit
// split categories, reshape to a long layout, and reduce to unique values
preserve
keep pubid SubjectCategory
quietly {
split SubjectCategory, parse(;) gen(cat)
reshape long cat, i(pubid)
bysort cat: keep if _n == 1
drop if mi(cat)
}
// show results and generate the wanted variable
list cat
local distinct = _N
dis _n as txt "distinct = " as res `distinct'
restore
gen wanted = `distinct'
end
runby distinct_categories, by(economist temps99) verbose