在Stata中,我有一组以pkg
开头的变量。在其当前状态下,其结尾为数字:pkg1
,pkg2
,pkg3
,pkg4
等等。
我需要将所有这些变量的结尾更改为字符串:pkgmz
,pkggmz
,pkgsp
,pkgsptc
等。
我有一列这些字符串结尾,我可以将其指定为本地列表。
例如:
local croplist mz gmz sp sptc mil cof suk tea ric
如何将数字结尾更改为字符串结尾?
我对代码的猜测可以在下面找到,???
表示我在哪里难倒:
local croplist crops mz gmz sp sptc mil cof suk tea ric
foreach x of varlist pkg* {
local new1 = substr(`x', 1, 3)
local new2 = ???
rename `x' ``new1'`new2''
label var ``new1'`new2'' "Avg district level `new2' price"
}
我想知道使用regexr()
命令是否更好,但想不出包含它的方法。
感谢任何帮助。
答案 0 :(得分:10)
此处无需调用正则表达式。你有新的后缀;前缀pkg
始终相同,因此不必重复提取它。问题的核心是同时在两个列表上循环。这是修复代码的一种方法。
local croplist mz gmz sp sptc mil cof suk tea ric
local j = 1
foreach x of varlist pkg* {
local sffx : word `j' of `croplist'
rename `x' pkg`sffx'
label var pkg`sffx' "Avg district level `sffx' price"
local ++j
}
注意,Stata 12+中的rename
可以处理此问题; regexr()
是一个函数,而不是一个命令; http://www.stata-journal.com/sjpdf.html?articlenum=pr0009中的一般性讨论(有点过时,但与主要问题相关);你的rename
命令上有太多的引号,所以它不起作用。
2018年7月30日编辑
我现在更倾向于使用gettoken
:
local croplist mz gmz sp sptc mil cof suk tea ric
foreach x of varlist pkg* {
gettoken sffx croplist: croplist
rename `x' pkg`sffx'
label var pkg`sffx' "Avg district level `sffx' price"
}
本地宏croplist
是一个堆栈。每次循环时,我们从堆栈中取出顶部项目,然后将其余部分留下。
每次循环
答案 1 :(得分:9)
这是另一种方法。 tokenize
在编号为1的宏中放置单独的单词。嵌套引用``j''
仅在初等代数中处理:首先计算内部宏引用。
tokenize "mz gmz sp sptc mil cof suk tea ric"
forval j = 1/9 {
rename pkg`j' pkg``j''
label var pkg``j'' "Avg district level ``j'' price"
}
答案 2 :(得分:7)
Ben在评论中提到了增加本地宏中保存的计数器的问题。
Stata的本地宏通常用于保持字符串;串 字符可以是数字,因此保持数字是一种特殊情况,但是 自然是一个非常有用的。仅此线程已经显示了几个 例子。它有助于牢记这一历史。长期的语法 基于表格
local macname <contents>
和
local macname = <expression>
第一个表单复制到macname
而第二个表单
在将结果分配给macname
之前进行评估。该
增加计数器的主要方法是多个版本
local j = `j' + 1
但语法
local ++j
现在允许。但是,虽然允许
local j++
不会像你期望的那样工作,尽管会发生什么是符合的 宏的第一个语法。
所以,如果你的背景看起来有点奇怪,那就是 可以理解,但本地宏用于字符串处理, 不算算。在这方面,马塔更像是主流。
我在
中写了关于循环和宏的教程Cox,N.J。2002.如何面对坚韧的名单。 Stata Journal 2(2): 202-222
,所有人都可以访问
答案 3 :(得分:2)
从Stata 12+开始,rename
可以通过多种方式处理此案例。
此方法创建一个包含变量名new_croplist
的新宏pkgmz pkggmz pkgsp pkgsptc pkgmil pkgcof pkgsuk pkgtea pkgric
,然后使用rename
将模式pkg<digits>
之后的变量重命名为new_croplist
中指定的名称}。 pkg
后面的数字不需要是连续的。
local croplist mz gmz sp sptc mil cof suk tea ric
local new_croplist
foreach name of local croplist {
local new_croplist `new_croplist' pkg`name'
}
rename pkg# (`new_croplist')
第二种方法使用新的rename
函数两次;和以前一样,这不需要原始名称中的连续数字。第一个命令将模式pkg<digits>
的变量重命名为croplist
中指定的名称。第二个命令将前缀pkg
添加到新变量名称。
rename pkg# (`croplist')
rename (`croplist') pkg=
在这两种情况下,通常在使用rename
命令(在Stata的文档中称为rename group
)时,旧变量名的数量必须与新变量名的数量相匹配,因此make确保pkg#
匹配的变量数与`croplist'中指定的新名称数相匹配。
答案 4 :(得分:1)
在@ Nick的优秀例子中使用计数器的另一种方法是使用
macro shift
:
clear
forvalues i = 1 / 9 {
generate pkg`i' = runiform()
}
local croplist mz gmz sp sptc mil cof suk tea ric
tokenize "`croplist'"
foreach var of varlist pkg* {
rename `var' pkg`1'
label var pkg`1' "Avg district level `1' price"
macro shift
}
您还可以使用ds
命令获取以pkg
开头的变量名称列表:
local croplist mz gmz sp sptc mil cof suk tea ric
tokenize "`croplist'"
ds pkg*
foreach var of varlist `r(varlist)' {
rename `var' pkg`1'
label var pkg`1' "Avg district level `1' price"
macro shift
}
在这两种情况下,你都会得到:
pkgmz float %9.0g Avg district level mz price
pkggmz float %9.0g Avg district level gmz price
pkgsp float %9.0g Avg district level sp price
pkgsptc float %9.0g Avg district level sptc price
pkgmil float %9.0g Avg district level mil price
pkgcof float %9.0g Avg district level cof price
pkgsuk float %9.0g Avg district level suk price
pkgtea float %9.0g Avg district level tea price
pkgric float %9.0g Avg district level ric price