foreach 使用前导 0 的数字列表

foreach using numlist of numbers with leading 0s

在 Stata 中,我正在尝试使用 foreach 循环,在其中循环遍历 05-11 中的数字。问题是我希望将 0 保留为值的一部分。我需要这样做,因为 0 出现在变量名称中。例如,我可能有名为 Y2005Y2006Var05Var06 等的变量。这是我尝试过的代码示例:

foreach year of numlist 05/09 {
   ...do stuff with Y20`year` or with Var`year`
}

这给了我一个错误,例如Y205 未找到。 (我认为正在发生的事情是它将 05 视为 5。)

另请注意,我不能在例如末尾添加 0 Y20 得到 Y200 因为 1011 值。

是否有变通方法或我没有做的明显事情?

可能有更好的解决方案,但这是解决方法:

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/910/11 区别对待的非常轻微的尴尬。

注意。要了解发生了什么,在非常简单的示例中以交互方式使用 display 通常会有所帮助。这里的细节是,Stata 在显示数字时对前导零无动于衷。通常这对你来说并不重要,或者当你意识到 Stata 不坚持对小于 1 的数字使用前导零时,这确实是一个功能。

. di 05
5

. di 0.3
.3

. di .3
.3

这里我们真的需要前导零,艺术是看到问题是字符串操作之一,"08" 等字符串恰好包含数字字符。同意这只有在理解时才显而易见。