与许多其他人一样,我经常在Stata中循环变量,运行一些估计命令,然后将结果提取到创建的变量来保存它们。当变量按顺序编号或以某种模式编号时(例如,集合中的偶数),这很简单。举个例子:
sysuse auto
gen var1 = uniform()
gen var2 = uniform()
gen var3 = uniform()
*Create variables to hold results
gen str4 varname=""
gen results=.
*Loop through three variables
foreach i of numlist 1/3{
replace varname="var`i'" in `i'
sum var`i'
replace results=r(mean) in `i'
}
但是,当变量不是数字和/或不是易于处理的顺序时,我经常想要做类似的事情。让我们说我想对自动数据集中的price
,mpg
,weight
和length
做同样的事情。如果我们将for循环设置为:
sysuse auto
gen str4 varname=""
gen results=.
foreach var of varlist price mpg weight length{
sum `var'
*Place values, in order, in rows?
}
然后我们需要一些方法来理解price
是列表中的第一个变量,因此它的结果应该放在第1行(或第1行中的名称,或者我们想要做的任何事情)。
这一定是可能的,但我会很感激一些建议。一个干净/非黑客的方式是理想的,因为我会做很多事情。
答案 0 :(得分:2)
您可以使用从1开始并在每次迭代结束时递增的本地计数器:
sysuse auto, clear
gen varname=""
gen mean=.
local i=1
foreach var of varlist price mpg weight {
quietly sum `var'
replace mean = r(mean) in `i'
replace varname = "`var'" in `i'
local ++i
}
答案 1 :(得分:2)
您也可以这样做。它看起来不像@Dimitriy V. Masterov解释的标准技术那样直接或简单,但它有其用途。
sysuse auto, clear
gen varname = ""
gen mean = .
local nvars : word count price mpg weight
tokenize "price mpg weight"
quietly forval j = 1/`nvars' {
sum ``j'', meanonly
replace mean = r(mean) in `j'
replace varname = "``j''" in `j'
}
一般要点是
单词用空格分隔,但双引号和复合双引号绑定更紧密。因此a
,b
和c
不出所料a b c
中的字词,Stata "is great"
您可以计算要循环的对象数量。它是字符串中的单词数。
将tokenize
应用于参数字符串会将该参数的单独单词映射到名为1
,2
的本地宏,依此类推。可能暗示的嵌套宏引用的解释方式与您从初等代数中猜测的一样:首先评估最内层的参数。
对于更复杂的问题,包括解压缩varlist,请同时查看unab
。