我有很多彼此嵌入的循环,我想在某些循环上使用条件逻辑,但我遇到了错误,并且想知道为什么这是不可能的。
换句话说,我有一套很长的代码(在我的实际示例中大约有 180 行)。我想运行此代码两次,但在第一个和第二个(可能还有更多)主循环中进行一些更改。一般来说,当我需要这样做时,我只需在代码中使用
if
语句,该语句仅针对某些循环激活。然而,在我当前的情况下,我的更改包括需要在两个主循环中运行不同的 foreach
语句。但由于某种原因,在这些循环上使用条件逻辑不起作用。
这是我想做的事情本质的 MWE(我的实际示例大约有 180 行):
sysuse auto2, clear
foreach i in abc def {
if "`i'"=="abc" foreach j in turn length trunk {
if "`i'"=="def" foreach j in displacement {
if "`i'"=="def" keep if _n<10
sum `j'
local a_`i'_`j' = r(mean)
}
if "`i'"=="abc" foreach j in turn length trunk {
if "`i'"=="def" foreach j in headroom trunk {
if "`i'"=="def" keep if _n<10
sum `j'
local b_`i'_`j' = r(min)
}
}
基本上,我有一堆代码想要循环两次,但是循环之间有一些差异。在第一个循环中,我想在循环中使用与第二个实例不同的变量集。我不想在第一个循环中进行样本限制,而我想在第二个循环中进行样本限制。 (在我的实际应用中,我在循环1和2之间也有不同的回归)。
我认为我可以使用逻辑(
if "``i'"=="..."
)来选择我想要使用的内部循环,但我收到了r(612)
(意外的文件结尾)错误。我最好的猜测是,来自 {
的 if "``i'"=="def" foreach j in displacement {
由于某种原因不会被忽略。
请注意,这个版本有效(我注释掉了第二个
if
语句),但显然没有达到我的需要:
sysuse auto2, clear
foreach i in abc def {
if "`i'"=="abc" foreach j in turn length trunk {
*if "`i'"=="def" foreach j in displacement {
if "`i'"=="def" keep if _n<10
sum `j'
local a_`i'_`j' = r(mean)
}
if "`i'"=="abc" foreach j in turn length trunk {
*if "`i'"=="def" foreach j in headroom trunk {
if "`i'"=="def" keep if _n<10
sum `j'
local b_`i'_`j' = r(min)
}
}
有没有办法将
if
与 foreach
一起使用(或者以其他方式挽救我的代码,而不必单独编写循环)?
请注意,这个问题与 Forvalues inside if statements有关。
这不是您寻求的答案,但坦白说,我什至不会尝试这样做。问题不在于没有办法做你想做的事——我还没有尝试过——只是你的代码太难了,任何人都无法轻松遵循。这里的任何人都包括未来的你。
让我们假设上游代码提供
abc
或 def
作为参数。我将按如下方式构建代码。
sysuse auto2, clear
if "`i'" == "abc" {
...
}
else if "`i'" == "def" {
...
}
你的 MWE 看起来仍然很奇怪,但是 FWIW
keep in 1/9
比keep if _n < 10
更直接
如果您只想要
summarize
中的平均值或最小值,请使用 meanonly
选项。
万一有人看到这个,我已经找到了解决方案,尽管我仍然不确定为什么它在原来的问题中不起作用。
您只需根据主循环的值定义一个变量列表即可。然后您可以在内循环中访问此变量,并避免使用两个
for
语句:
sysuse auto2, clear
foreach i in abc def {
if "`i'"=="abc" local vars turn length trunk
if "`i'"=="def" local vars displacement
foreach j in `vars' {
if "`i'"=="def" keep if _n<10
sum `j'
local a_`i'_`j' = r(mean)
}
}