本地中的本地在程序中评估为空
A local within a local evaluates as empty in a program
我正在尝试编写一个小程序,它只需要一个变量列表,returns 一个包含数据集中实际变量的子列表。
我在一个 do
文件中多次这样做(不是按顺序,所以没有循环),所以只需要一个快速程序比每次都有效地复制这段代码更容易。
程序的简化版本如下。主要问题出现在第 6 行。程序的第一个参数应该是包含变量名的本地宏的名称,以便与数据集中的变量名进行比较。因此,例如,如果局部宏是 list1
,程序的第一个参数是 list1
,我想存储一个新的局部宏,vlist
,它包含所有变量在 list1
。
但是当我尝试这样做时:
``1''
生成的本地宏 vlist
只是空的,而本地 allvars
没问题。
我的程序代码如下:
clear
cap program drop lm
program define lm
* Create a new local, vlist, that is all the variables in the local macro identified in argument 1
local vlist ``1''
* Create a new local, allvars, that is all variables in teh dataset
qui ds, a
local allvars `r(varlist)'
* Display both macros, to illustrate that vlist is empty, while allvars contains all variables
di as text "vlist: " as result "`vlist'"
di as text "allvars: " as result "`allvars'" _newline
* Create a new local macro that is the intersection of the two lists (if it worked)
local `1'_inter : list vlist & allvars
* Display different messages depending on the outcome (e.g. if a list was created, or empty)
if missing("``1'_inter'") di as error "There are no common variables between `1' and the dataset."
else di as result "`1' intersection with varlist _all now stored as local: `1'_inter"
end
clear
input float(var1 var2 var3 var4 var5) // Input irrelevant data
. . . . .
end
/* Next, create a macro with a list of variables that are in the dataset
(e.g. var1 and var2), and even some that are not in teh data (var7). */
local list1 var1 var2 var7
* Execute the list-match program
lm list1
如您所见,本地 vlist
最终为空,因此列表之间没有交集。
知道我在这里做错了什么吗?
我确定是双局部宏,但我不知道如何修复它。
宏参考中的宏
``1''
评价如下。首先,宏 1
是您作为命令参数键入的第一个内容,在您的示例中是 list1
,因此替换 Stata 然后会看到
`list1'
并且整个命令现在被评估为
local vlist `list1'
然后评估如下。本地宏 list1
中有什么?完全没有,或者是一个空字符串,因为在程序的那个点不存在这样的本地宏(并且在其他任何地方创建的任何其他本地宏都是不可见的,因为这就是本地的意思:本地程序 space 相关) .所以下一个 Stata 看到
local vlist
由此您可以同时创建一个本地宏并将其清空,从而销毁它。
解决方案是你打算写
local vlist "`1'"
或者只是
args vlist
然而,这还没有结束。命令
lm list1
提及您刚刚创建的本地宏的名称。但是将本地宏的名称传递给另一个程序是徒劳的,因为另一个程序看不到宏的内容。你必须传递内容。
此外:程序随后需要修改,因为您可能想将多个名称传递给它,如果您将它们用双引号括起来,它们只会被视为一个参数。
FWIW,您描述的问题似乎是由 SSC 的 isvar
解决的。这是:
*! NJC 1.0.0 20 Sept 2005
program isvar, rclass
version 8
syntax anything
foreach v of local anything {
capture unab V : `v'
if _rc == 0 local varlist `varlist' `V'
else local badlist `badlist' `v'
}
di
if "`varlist'" != "" {
local n : word count `varlist'
local what = plural(`n', "variable")
di as txt "{p}`what': " as res "`varlist'{p_end}"
return local varlist "`varlist'"
}
if "`badlist'" != "" {
local n : word count `badlist'
local what = plural(`n', "not variable")
di as txt "{p}`what': " as res "`badlist'{p_end}"
return local badlist "`badlist'"
}
end
我喜欢 ds
但我不会在这里使用它。您可能会调用数千个变量名称,只是为了检查数据集中是否有几个名称。
关于风格的最后评论
local list1 var1 var2 var7
lm list1
还不如
lm var1 var2 var7
因为当您可以直接传递名称时,将名称放入包(本地宏)并使用包的名称没有任何价值。如前所述,在您修复它之前,这不会与您的程序一起使用,但它可以与 isvar
一起使用。
我正在尝试编写一个小程序,它只需要一个变量列表,returns 一个包含数据集中实际变量的子列表。
我在一个 do
文件中多次这样做(不是按顺序,所以没有循环),所以只需要一个快速程序比每次都有效地复制这段代码更容易。
程序的简化版本如下。主要问题出现在第 6 行。程序的第一个参数应该是包含变量名的本地宏的名称,以便与数据集中的变量名进行比较。因此,例如,如果局部宏是 list1
,程序的第一个参数是 list1
,我想存储一个新的局部宏,vlist
,它包含所有变量在 list1
。
但是当我尝试这样做时:
``1''
生成的本地宏 vlist
只是空的,而本地 allvars
没问题。
我的程序代码如下:
clear
cap program drop lm
program define lm
* Create a new local, vlist, that is all the variables in the local macro identified in argument 1
local vlist ``1''
* Create a new local, allvars, that is all variables in teh dataset
qui ds, a
local allvars `r(varlist)'
* Display both macros, to illustrate that vlist is empty, while allvars contains all variables
di as text "vlist: " as result "`vlist'"
di as text "allvars: " as result "`allvars'" _newline
* Create a new local macro that is the intersection of the two lists (if it worked)
local `1'_inter : list vlist & allvars
* Display different messages depending on the outcome (e.g. if a list was created, or empty)
if missing("``1'_inter'") di as error "There are no common variables between `1' and the dataset."
else di as result "`1' intersection with varlist _all now stored as local: `1'_inter"
end
clear
input float(var1 var2 var3 var4 var5) // Input irrelevant data
. . . . .
end
/* Next, create a macro with a list of variables that are in the dataset
(e.g. var1 and var2), and even some that are not in teh data (var7). */
local list1 var1 var2 var7
* Execute the list-match program
lm list1
如您所见,本地 vlist
最终为空,因此列表之间没有交集。
知道我在这里做错了什么吗?
我确定是双局部宏,但我不知道如何修复它。
宏参考中的宏
``1''
评价如下。首先,宏 1
是您作为命令参数键入的第一个内容,在您的示例中是 list1
,因此替换 Stata 然后会看到
`list1'
并且整个命令现在被评估为
local vlist `list1'
然后评估如下。本地宏 list1
中有什么?完全没有,或者是一个空字符串,因为在程序的那个点不存在这样的本地宏(并且在其他任何地方创建的任何其他本地宏都是不可见的,因为这就是本地的意思:本地程序 space 相关) .所以下一个 Stata 看到
local vlist
由此您可以同时创建一个本地宏并将其清空,从而销毁它。
解决方案是你打算写
local vlist "`1'"
或者只是
args vlist
然而,这还没有结束。命令
lm list1
提及您刚刚创建的本地宏的名称。但是将本地宏的名称传递给另一个程序是徒劳的,因为另一个程序看不到宏的内容。你必须传递内容。
此外:程序随后需要修改,因为您可能想将多个名称传递给它,如果您将它们用双引号括起来,它们只会被视为一个参数。
FWIW,您描述的问题似乎是由 SSC 的 isvar
解决的。这是:
*! NJC 1.0.0 20 Sept 2005
program isvar, rclass
version 8
syntax anything
foreach v of local anything {
capture unab V : `v'
if _rc == 0 local varlist `varlist' `V'
else local badlist `badlist' `v'
}
di
if "`varlist'" != "" {
local n : word count `varlist'
local what = plural(`n', "variable")
di as txt "{p}`what': " as res "`varlist'{p_end}"
return local varlist "`varlist'"
}
if "`badlist'" != "" {
local n : word count `badlist'
local what = plural(`n', "not variable")
di as txt "{p}`what': " as res "`badlist'{p_end}"
return local badlist "`badlist'"
}
end
我喜欢 ds
但我不会在这里使用它。您可能会调用数千个变量名称,只是为了检查数据集中是否有几个名称。
关于风格的最后评论
local list1 var1 var2 var7
lm list1
还不如
lm var1 var2 var7
因为当您可以直接传递名称时,将名称放入包(本地宏)并使用包的名称没有任何价值。如前所述,在您修复它之前,这不会与您的程序一起使用,但它可以与 isvar
一起使用。