本地宏的使用
Use of local macro
我想从我的原始数据中写入六个临时数据文件,并保留以下变量:
- temp1: v1-v18
- temp2:v1-v5 v19-v31
- temp3:v1-v5 v32-v44
- temp4:v1-v5 v45-v57
- temp5:v1-v5 v58-v70
- temp6: v1-v5 v71-v84
我试过以下方法:
forvalues i =1(1)6 {
preserve
local j = 6 + (`i'-1)*13
local k = `j'+12
keep v1-v18 if `j'==6
keep v1-v5 v`i'-v`k' if `i'>6 & `j'<71
keep v1-v5 v71-v84 if `j'==71
export delimited using temp`i'.csv, delimiter(";") novarnames replace
restore
}
我收到 invalid syntax
错误。问题在于 keep
语句。具体来说,带有本地宏的 if
条件似乎违反语法规则。
我认为您的部分困惑是由于误解了 if
限定符与 if
命令。
if
命令计算一个表达式:如果该表达式为真,则执行后面的操作。 if
命令应用于评估单个表达式,在本例中为宏的值。
您可以使用 if
限定符,例如,当您想要 regress y x if x > 2
或 replace x = . if x <= 2
等时。请参阅 here 了解简短说明。
您的语法还有其他问题。您不能让代码跟在 forvalues
循环中的左大括号在同一行,也不能在跟右大括号在同一行。您还可以使用本地 i
来调节您的 keep
。我认为你的意思是在这里使用 j
,因为 i
只是用于迭代循环,而不是标识变量后缀。
此外,这里的逻辑似乎可行,但似乎不是很通用或高效。我想有更好的方法可以做到这一点,但我现在没有时间玩弄它 - 也许以后会更新。
无论如何,我认为与您尝试过的最相似的正确语法如下所示。
clear *
set more off
set obs 5
forvalues i = 1/84 {
gen v`i' = runiform()
}
forvalues i =1/6 {
preserve
local j = 6 + (`i'-1)*13
local k = `j'+12
if `j' == 6 {
keep v1-v18
}
else if `j' > 6 & `j' < 71 {
keep v1-v5 v`j'-v`k'
}
else keep v1-v5 v71-v84
ds
di
restore
}
我在这里使用 ds
来简单地列出数据中的变量,然后 di
显示一个空行作为分隔符,但您可以简单地插入您的 export
它应该工作得很好。
如果您真的需要临时数据文件,要考虑的另一件事是考虑使用 tempfile
,这样您就不会向磁盘写入任何内容。您可能会使用
forvalues i = 1/6 {
tempfile temp`i'
// other commands
save `temp`i''
}
这将创建六个 Stata 数据文件 temp1
- temp6
,它们将保存在内存中,直到程序终止。
我想从我的原始数据中写入六个临时数据文件,并保留以下变量:
- temp1: v1-v18
- temp2:v1-v5 v19-v31
- temp3:v1-v5 v32-v44
- temp4:v1-v5 v45-v57
- temp5:v1-v5 v58-v70
- temp6: v1-v5 v71-v84
我试过以下方法:
forvalues i =1(1)6 {
preserve
local j = 6 + (`i'-1)*13
local k = `j'+12
keep v1-v18 if `j'==6
keep v1-v5 v`i'-v`k' if `i'>6 & `j'<71
keep v1-v5 v71-v84 if `j'==71
export delimited using temp`i'.csv, delimiter(";") novarnames replace
restore
}
我收到 invalid syntax
错误。问题在于 keep
语句。具体来说,带有本地宏的 if
条件似乎违反语法规则。
我认为您的部分困惑是由于误解了 if
限定符与 if
命令。
if
命令计算一个表达式:如果该表达式为真,则执行后面的操作。 if
命令应用于评估单个表达式,在本例中为宏的值。
您可以使用 if
限定符,例如,当您想要 regress y x if x > 2
或 replace x = . if x <= 2
等时。请参阅 here 了解简短说明。
您的语法还有其他问题。您不能让代码跟在 forvalues
循环中的左大括号在同一行,也不能在跟右大括号在同一行。您还可以使用本地 i
来调节您的 keep
。我认为你的意思是在这里使用 j
,因为 i
只是用于迭代循环,而不是标识变量后缀。
此外,这里的逻辑似乎可行,但似乎不是很通用或高效。我想有更好的方法可以做到这一点,但我现在没有时间玩弄它 - 也许以后会更新。
无论如何,我认为与您尝试过的最相似的正确语法如下所示。
clear *
set more off
set obs 5
forvalues i = 1/84 {
gen v`i' = runiform()
}
forvalues i =1/6 {
preserve
local j = 6 + (`i'-1)*13
local k = `j'+12
if `j' == 6 {
keep v1-v18
}
else if `j' > 6 & `j' < 71 {
keep v1-v5 v`j'-v`k'
}
else keep v1-v5 v71-v84
ds
di
restore
}
我在这里使用 ds
来简单地列出数据中的变量,然后 di
显示一个空行作为分隔符,但您可以简单地插入您的 export
它应该工作得很好。
如果您真的需要临时数据文件,要考虑的另一件事是考虑使用 tempfile
,这样您就不会向磁盘写入任何内容。您可能会使用
forvalues i = 1/6 {
tempfile temp`i'
// other commands
save `temp`i''
}
这将创建六个 Stata 数据文件 temp1
- temp6
,它们将保存在内存中,直到程序终止。