用嵌套循环 Stata 填充变量
Fill variable with a nested loop Stata
我正在尝试在 Stata 中创建这样的变量:
date
2012_1
2012_2
2013_1
2013_2
下一个循环:
forval y=2012/2013{
forval m=1/2{
display `m'
gen date = `y'_`m'
}
}
但我在第一次迭代中遇到此错误:2012_1 invalid name
。抱歉,如果问题很明显,我是 Stata 的新手。
你的代码有不少问题。我会一一介绍。
`y'_`m'
评估为 2012_1 第一次迭代。由于它包含下划线,因此不能将其解释为数字。要被解释为字符串值,需要将其括在“”中。最后,Stata 试图将其解释为变量,但 2012_1 不是有效名称(必须以字母开头),因此出现错误。
您可以将您的值括在引号中以创建字符串变量:"`y'_`m'"
。这将适用于第一次迭代,但第二次迭代会出现错误,因为变量 'date' 已经存在。创建变量后,只能replace
它
最后,您的代码没有说明哪个值对应哪个观察值。即使您修复了已经提到的问题,您的变量也只会包含所有观察值的相同值,即循环中最后一次迭代的值。要仅替换一个观察值,您必须指定 in i
,其中 i 是观察值编号。
总而言之,这将是修改后的代码:
gen date = "."
local obs = 1
forval y=2012/2013{
forval m=1/2{
display `m'
replace date = "`y'_`m'" in `obs'
local ++obs
}
}
但是,我不建议创建这种类型的日期变量,因为字符串变量的用途有限。 Stata 的内部日期格式是最方便的。如果您的值 1 和 2 代表半年,您可以创建半年一次的日期变量,请参阅 help datetime
了解有关如何执行此操作的信息。另一种选择是创建一个包含年份的数值变量,以及一个包含 1 和 2 的第二个数值变量。
你面临的问题比你在这里意识到的要多,但都很简单。
循环的直接问题是 2012_1
之类的值是您打算作为变量的值,但如果是这样,它必须明确地是一个字符串,由""
。原因是下划线 _
只能作为字符串的一部分。 Stata 显然对您的命令感到困惑。错误消息不太适合这种情况,尽管 2012_1
不是可接受的名称是正确的,意思是变量或标量的名称。
如果您修复了该问题,您的下一个问题将是第二次循环时变量已经存在,因此 generate
是不可接受的。您需要 replace
。因此,generate
语句应该放在循环之外。
再一次,即使解决了这些问题,你的循环所做的就是每次都用相同的值覆盖变量。在循环结束时,所有观察值都将包含常量值 2013_2
。
长期来看,还是有问题。显然你想要一个月度日期变量,但像这样的月度日期变量在 Stata 中用处不大。它们以正确的顺序排序,但它们对于统计或图形基本上没有用。
这是一个更好的主意:
generate mdate = .
local i = 1
forval y = 2012/2013 {
forval m = 1/2 {
replace mdate = ym(`y', `m') in `i'
local ++i
}
}
那还是不好的风格。我猜你并不真的只想要第 1 个月和第 2 个月,但我们不知道你真正想要什么。
在 Stata 中执行此操作:
clear
set obs 48
generate mdate = ym(2011, 12) + _n
format mdate %tm
list
了解更好的方法——完全没有循环。
我正在尝试在 Stata 中创建这样的变量:
date
2012_1
2012_2
2013_1
2013_2
下一个循环:
forval y=2012/2013{
forval m=1/2{
display `m'
gen date = `y'_`m'
}
}
但我在第一次迭代中遇到此错误:2012_1 invalid name
。抱歉,如果问题很明显,我是 Stata 的新手。
你的代码有不少问题。我会一一介绍。
`y'_`m'
评估为 2012_1 第一次迭代。由于它包含下划线,因此不能将其解释为数字。要被解释为字符串值,需要将其括在“”中。最后,Stata 试图将其解释为变量,但 2012_1 不是有效名称(必须以字母开头),因此出现错误。
您可以将您的值括在引号中以创建字符串变量:"`y'_`m'"
。这将适用于第一次迭代,但第二次迭代会出现错误,因为变量 'date' 已经存在。创建变量后,只能replace
它
最后,您的代码没有说明哪个值对应哪个观察值。即使您修复了已经提到的问题,您的变量也只会包含所有观察值的相同值,即循环中最后一次迭代的值。要仅替换一个观察值,您必须指定 in i
,其中 i 是观察值编号。
总而言之,这将是修改后的代码:
gen date = "."
local obs = 1
forval y=2012/2013{
forval m=1/2{
display `m'
replace date = "`y'_`m'" in `obs'
local ++obs
}
}
但是,我不建议创建这种类型的日期变量,因为字符串变量的用途有限。 Stata 的内部日期格式是最方便的。如果您的值 1 和 2 代表半年,您可以创建半年一次的日期变量,请参阅 help datetime
了解有关如何执行此操作的信息。另一种选择是创建一个包含年份的数值变量,以及一个包含 1 和 2 的第二个数值变量。
你面临的问题比你在这里意识到的要多,但都很简单。
循环的直接问题是
2012_1
之类的值是您打算作为变量的值,但如果是这样,它必须明确地是一个字符串,由""
。原因是下划线_
只能作为字符串的一部分。 Stata 显然对您的命令感到困惑。错误消息不太适合这种情况,尽管2012_1
不是可接受的名称是正确的,意思是变量或标量的名称。如果您修复了该问题,您的下一个问题将是第二次循环时变量已经存在,因此
generate
是不可接受的。您需要replace
。因此,generate
语句应该放在循环之外。再一次,即使解决了这些问题,你的循环所做的就是每次都用相同的值覆盖变量。在循环结束时,所有观察值都将包含常量值
2013_2
。长期来看,还是有问题。显然你想要一个月度日期变量,但像这样的月度日期变量在 Stata 中用处不大。它们以正确的顺序排序,但它们对于统计或图形基本上没有用。
这是一个更好的主意:
generate mdate = .
local i = 1
forval y = 2012/2013 {
forval m = 1/2 {
replace mdate = ym(`y', `m') in `i'
local ++i
}
}
那还是不好的风格。我猜你并不真的只想要第 1 个月和第 2 个月,但我们不知道你真正想要什么。
在 Stata 中执行此操作:
clear
set obs 48
generate mdate = ym(2011, 12) + _n
format mdate %tm
list
了解更好的方法——完全没有循环。