foreach 使用前导 0 的数字列表
foreach using numlist of numbers with leading 0s
在 Stata 中,我正在尝试使用 foreach
循环,在其中循环遍历 05
-11
中的数字。问题是我希望将 0
保留为值的一部分。我需要这样做,因为 0
出现在变量名称中。例如,我可能有名为 Y2005
、Y2006
、Var05
、Var06
等的变量。这是我尝试过的代码示例:
foreach year of numlist 05/09 {
...do stuff with Y20`year` or with Var`year`
}
这给了我一个错误,例如Y205
未找到。 (我认为正在发生的事情是它将 05
视为 5
。)
另请注意,我不能在例如末尾添加 0
Y20
得到 Y200
因为 10
和 11
值。
是否有变通方法或我没有做的明显事情?
可能有更好的解决方案,但这是解决方法:
clear
set more off
*----- example data -----
input ///
var2008 var2009 var2010 var2011 var2012
0 1 2 3 4
end
*----- what you want -----
numlist "10(1)12"
local nums 08 09 `r(numlist)'
foreach x of local nums {
display var20`x'
}
01...09
可以手动插入。其余的你用 numlist
构建。将所有这些放在 local
中,最后在循环中使用它。
正如你所说,你的代码的问题在于 Stata 将在给定 05
时读取 5
,如果你告诉它是一个数字(你使用 numlist
在循环中)。
另一个解决方案是使用 if
命令来计算循环值中的字符数,然后如果需要,您可以通过重新分配本地来添加前导零。
clear
input var2008 var2009 var2010 var2011 var2012
0 1 2 3 4
end
foreach year of numlist 08/12{
if length("`year'") == 1 local year 0`year'
di var20`year'
}
另一种解决方法是
forval y = 5/11 {
local Y : di %02.0f `y'
<code using local Y, which must be treated as a string>
}
中线可以根据
`: di %02.0f `y''
这样可以避免使用另一个宏,但代价是使代码更加隐晦。
在这里我利用了一个额外的事实,即 foreach
在这样一个简单的 numlist 上可以用 forvalues
替换。
此处的主要技巧已记录在案 here。这个技巧避免了将 5/9
与 10/11
区别对待的非常轻微的尴尬。
注意。要了解发生了什么,在非常简单的示例中以交互方式使用 display
通常会有所帮助。这里的细节是,Stata 在显示数字时对前导零无动于衷。通常这对你来说并不重要,或者当你意识到 Stata 不坚持对小于 1 的数字使用前导零时,这确实是一个功能。
. di 05
5
. di 0.3
.3
. di .3
.3
这里我们真的需要前导零,艺术是看到问题是字符串操作之一,"08"
等字符串恰好包含数字字符。同意这只有在理解时才显而易见。
在 Stata 中,我正在尝试使用 foreach
循环,在其中循环遍历 05
-11
中的数字。问题是我希望将 0
保留为值的一部分。我需要这样做,因为 0
出现在变量名称中。例如,我可能有名为 Y2005
、Y2006
、Var05
、Var06
等的变量。这是我尝试过的代码示例:
foreach year of numlist 05/09 {
...do stuff with Y20`year` or with Var`year`
}
这给了我一个错误,例如Y205
未找到。 (我认为正在发生的事情是它将 05
视为 5
。)
另请注意,我不能在例如末尾添加 0
Y20
得到 Y200
因为 10
和 11
值。
是否有变通方法或我没有做的明显事情?
可能有更好的解决方案,但这是解决方法:
clear
set more off
*----- example data -----
input ///
var2008 var2009 var2010 var2011 var2012
0 1 2 3 4
end
*----- what you want -----
numlist "10(1)12"
local nums 08 09 `r(numlist)'
foreach x of local nums {
display var20`x'
}
01...09
可以手动插入。其余的你用 numlist
构建。将所有这些放在 local
中,最后在循环中使用它。
正如你所说,你的代码的问题在于 Stata 将在给定 05
时读取 5
,如果你告诉它是一个数字(你使用 numlist
在循环中)。
另一个解决方案是使用 if
命令来计算循环值中的字符数,然后如果需要,您可以通过重新分配本地来添加前导零。
clear
input var2008 var2009 var2010 var2011 var2012
0 1 2 3 4
end
foreach year of numlist 08/12{
if length("`year'") == 1 local year 0`year'
di var20`year'
}
另一种解决方法是
forval y = 5/11 {
local Y : di %02.0f `y'
<code using local Y, which must be treated as a string>
}
中线可以根据
`: di %02.0f `y''
这样可以避免使用另一个宏,但代价是使代码更加隐晦。
在这里我利用了一个额外的事实,即 foreach
在这样一个简单的 numlist 上可以用 forvalues
替换。
此处的主要技巧已记录在案 here。这个技巧避免了将 5/9
与 10/11
区别对待的非常轻微的尴尬。
注意。要了解发生了什么,在非常简单的示例中以交互方式使用 display
通常会有所帮助。这里的细节是,Stata 在显示数字时对前导零无动于衷。通常这对你来说并不重要,或者当你意识到 Stata 不坚持对小于 1 的数字使用前导零时,这确实是一个功能。
. di 05
5
. di 0.3
.3
. di .3
.3
这里我们真的需要前导零,艺术是看到问题是字符串操作之一,"08"
等字符串恰好包含数字字符。同意这只有在理解时才显而易见。