我列出了从2000年到2004年的5年中50个州的名单
State year
Alaska 2000
Alaska 2001
Alaska 2002
Alaska 2003
Alaska 2004
Alabama 2000
Alabama 2001
Alabama 2002
Alabama 2003
Alabama 2004
Arizona 2000
Arizona 2001
Arizona 2002
Arizona 2003
Arizona 2004
Arkansas 2000
Arkansas 2001
Arkansas 2002
Arkansas 2003
Arkansas 2004
Colorado 2000
Colorado 2001
Colorado 2002
Colorado 2003
Colorado 2004
我想使用foreach
创建一个local
循环,仅包含阿拉巴马州和科罗拉多州。
最终目标是要有一个名为dummy
的虚拟变量,在2002年至2004年的几年中,所有州将为0
,阿拉巴马州和科罗拉多州将为1
。
这将是最终的数据集:
State year dummy
Alaska 2000 0
Alaska 2001 0
Alaska 2002 0
Alaska 2003 0
Alaska 2004 0
Alabama 2000 0
Alabama 2001 0
Alabama 2002 1
Alabama 2003 1
Alabama 2004 1
Arizona 2000 0
Arizona 2001 0
Arizona 2002 0
Arizona 2003 0
Arizona 2004 0
Arkansas 2000 0
Arkansas 2001 0
Arkansas 2002 0
Arkansas 2003 0
Arkansas 2004 0
Colorado 2000 0
Colorado 2001 0
Colorado 2002 1
Colorado 2003 1
Colorado 2004 1
这是我到目前为止尝试过的。
use "States.dta", replace
gen dummy = 0
local States "Alabama Colorado"
local i=1
foreach ii of local States {
replace dummy_treated = 1 if States == `ii' & year >=2002
local i=`i' + 1
}
运行此命令时,它只会为阿拉巴马州产生输出,不包括科罗拉多州。 当我关闭文件并重新运行程序时,错误消息显示
Alabama not found
r(111);
该如何解决?
答案 0 :(得分:1)
我的回答分为两个部分。
首先:您可以通过一个命令行来避免这种方法
gen wanted = inlist(States, "Alabama", "Colorado") ///
& inrange(year, 2002, 2004)
不需要循环。当关节条件为true时,此处的右侧求值为1,而当条件为false时,右侧求为0,这正是指标变量(您说“虚拟”,最好避免使用该术语,但您可以使用)的精确值。
第二:您的代码有什么问题?您的报告自相矛盾,因为您声明该代码只能工作一次,但不能重复。我只能相信,如果您正在使用不同版本的数据。您收到的错误消息很容易解释。您正在测试
States == Alabama
只有当您具有名称为Alabama
的变量或具有相同名称的字符串标量时,Stata才有意义。您没有这样的变量或标量,并且Stata抛出命令,因为它找不到您认为要使用的命令。出现错误是因为States
显然是一个字符串变量,您需要测试
States == "Alabama"
双引号对于指定文字字符串值而不是字符串变量或标量的名称至关重要。
尽管这是完全不必要的,但是如果给定一个字符串变量States
且其值类似于Alabama
,这将是合法的循环:
gen dummy = 0
foreach s in Alabama Colorado {
replace dummy = 1 if inlist(States, "`s'") & inrange(year, 2002, 2004)
}
year >= 2002
对于您的示例来说很好,但是在这种情况下,我提到inrange()
是有用的功能。