loops - 如何在Stata中将两个循环变成一个双循环?
问题描述
我有这两个功能(工作)循环:
* Loop that creates 1/0 variables
foreach x in m1 m2 m3 m4 {
gen yn_`x' = beforedate * `x'
}
* Loop that creates four dichotomous lag variables
foreach x in 0 3 12 18 {
gen lag`x' = refdate > (date + 30 * `x')
}
我想将循环组合成一个双循环。以下是我对此的尝试,但它不起作用。
foreach x in m1 m2 m3 m4 {
foreach y in 0 3 12 18 {
gen yn_`x' = beforedate * `x'
gen lag`y' = refdate > (date + 30 * `y')
}
}
我得到的错误(下)。这个错误似乎与我的间距和制表符有关(但我对此并不完全确定)。
变量 yn_m1 已经定义。
我的数据样本:
* Example generated by -dataex-. To install: ssc install dataex
clear
input float id byte(m1 m2 m3 m4) float(beforedate refdate) int date
1 . . . . 0 16594 .
2 . . . . 0 18228 .
3 . . . . 0 18238 .
4 . . . . 0 18237 .
5 0 0 0 0 1 18016 16324
6 . . . . 0 16324 .
7 . . . . 0 16914 .
8 1 0 0 0 1 18226 17333
9 . . . . 0 17096 .
10 0 0 0 0 0 17961 17962
11 . . . . 0 16978 .
12 . . . . 0 17844 .
13 . . . . 0 17207 .
14 . . . . 0 17141 .
15 . . . . 0 16338 .
16 . . . . 0 16100 .
17 . . . . 0 17498 .
18 . . . . 0 17394 .
19 . . . . 0 18207 .
20 . . . . 0 18043 .
21 . . . . 0 16851 .
22 . . . . 0 18027 .
23 . . . . 0 17723 .
24 . . . . 0 16475 .
25 1 1 0 0 1 16097 16079
26 . . . . 0 16613 .
27 . . . . 0 17350 .
28 . . . . 0 17972 .
29 . . . . 0 18009 .
30 1 0 0 0 0 18008 18184
31 . . . . 0 16840 .
32 0 1 0 0 1 18179 17370
33 . . . . 0 16224 .
34 . . . . 0 17400 .
35 . . . . 0 17015 .
36 . . . . 0 16880 .
37 . . . . 0 16637 .
38 . . . . 0 16566 .
39 . . . . 0 17056 .
40 . . . . 0 18073 .
41 . . . . 0 17076 .
42 0 1 0 0 0 16179 17447
43 . . . . 0 16422 .
44 . . . . 0 16184 .
45 . . . . 0 16495 .
46 . . . . 0 17168 .
47 1 1 0 0 0 18001 18001
48 . . . . 0 16649 .
49 . . . . 0 17150 .
50 . . . . 0 17426 .
51 . . . . 0 16237 .
52 1 0 0 0 0 17681 17841
53 0 1 0 0 1 17874 16377
54 . . . . 0 16992 .
55 0 1 0 0 1 16377 16307
56 0 1 0 0 0 18066 18149
57 . . . . 0 16428 .
58 . . . . 0 18256 .
59 . . . . 0 16845 .
60 0 1 0 0 1 17997 16631
61 . . . . 0 17899 .
62 . . . . 0 16849 .
63 . . . . 0 16687 .
64 . . . . 0 18074 .
65 . . . . 0 17428 .
66 . . . . 0 16140 .
67 0 1 0 0 0 17938 18004
68 . . . . 0 16326 .
69 . . . . 0 17362 .
70 0 1 0 0 1 16954 16079
71 0 0 0 0 1 17974 16853
72 1 0 0 0 0 17077 17892
73 1 0 1 0 0 16453 17787
74 . . . . 0 18148 .
75 . . . . 0 18042 .
76 . . . . 0 16156 .
77 . . . . 0 16509 .
78 . . . . 0 17285 .
79 . . . . 0 16348 .
80 . . . . 0 17908 .
81 1 1 0 0 0 17932 17992
82 . . . . 0 17436 .
83 . . . . 0 17900 .
84 . . . . 0 16644 .
85 0 0 0 0 0 17170 18108
86 . . . . 0 17292 .
87 . . . . 0 16874 .
end
format %td refdate
format %d date
解决方案
要执行 Nick 和 Wouter 的建议,您需要将要传递的两个列表foreach
放入本地,然后将它们循环在一起:
* loops in parallel
local mlist "m1 m2 m3 m4"
local nlist "0 3 12 18"
local n : word count `nlist'
local m : word count `mlist'
assert `n'==`m' // require same length
forvalues i = 1/`n' {
local a : word `i' of `mlist'
local b : word `i' of `nlist'
gen yn_`a'_II = beforedate * `a'
gen lag`b'_II = refdate > (date + 30 * `b')
}
即使此示例不是其中之一,此技术在许多情况下也很有用。
编辑新泽西州
如果您可以清楚地看到每种情况下都有四个元素,则可以将其精简为
local nlist "0 3 12 18"
forvalues i = 1/4 {
local n : word `i' of `nlist'
gen yn_m`i'_II = beforedate * m'i'
gen lag`b'_II = refdate > (date + 30 * `n')
}
确实如此
tokenize "0 3 12 18"
forvalues i = 1/4 {
gen yn_m`i'_II = beforedate * m'i'
gen lag`b'_II = refdate > (date + 30 * ``i'')
}
虽然你可以这样做,但我(NJC)认为合并这样不相关的循环并不是特别好的风格。阅读您的代码的人可能会对此感到困惑,除非您添加解释性注释,否则会破坏编码中的任何整洁性。
编辑结束
推荐阅读
- python - 从 Windows shell 调用 Anaconda Python 时导入失败
- python - 如何从响应中删除 u(unicode) 并使用机器人框架在正文中替换它?
- strapi - Strapi 关系的 POST 详细信息
- .net - Azure 服务总线 - 更新锁无法正常工作
- javascript - 如何在 ReactJS 中渲染嵌套数据?
- sql-server - Active Directory 组的 SqlTableDependency 权限问题
- css - 如何修复顶部导航栏粘滞位置?
- .net-core - Raspberry Pi 4 上 Visual Studio 2019 CE 的 Dotnetcore 3.0 远程调试 - 权限不足
- ruby-on-rails - 如何在 rake 任务中读取 csv 文件
- excel - VBA:如何知道图表是否在单独的工作表中?