我正在清理Stata中具有数字值的字符串变量,但偶尔会将值格式化为范围,如1-50
或1-3
等。
当我尝试解串这些变量时,这些讨厌的范围阻止我这样做。
我想要做的是将范围替换为第一个数字的平均值和范围中的最后一个数字。我尝试了以下字符串函数来执行此操作:
replace `var' = ((regexs(1) + regexs(3))/2) if regexm(`var', "([0-9]*)([\-])([0-9]*)")
但是,Stata无法理解平均值((regexs(1) + regexs(3))/2)
,因为它将regexs(1)
和regexs(2)
视为子字符串。
我知道我可以通过创建新变量来实现这一点,但我正在使用的数据有数千个变量,所以我更愿意只替换现有的字符串。
关于如何做到这一点的任何想法?
提前致谢
答案 0 :(得分:2)
这是一种将字符串拆分为2的方法,并将其解压缩:
#delimit;
clear;
set obs 4;
input str4 x str4 y;
"13" "4-7";
"1-50" "7";
"1-3" "9-20";
"" "4";
foreach var of varlist x y {;
split `var', parse("-") destring;
egen clean_`var' = rowmean(`var'1 `var'2);
drop `var'1 `var'2;
};
答案 1 :(得分:2)
您可以使用real()
将字符串转换为数字。
clear
set more off
input ///
str6 range
"1-50"
"1-3"
end
list
gen range2 = (real(regexs(1)) + real(regexs(3)))/2 if ///
regexm(range, "([0-9]*)([\-])([0-9]*)")
list
但是,如果不是严格需要正则表达式(我无法确定),我会选择split
,就像Dimitriy已经指出的那样。注意我生成了一个新变量。摆脱原始,一般来说,不是很好的做法。
答案 2 :(得分:1)
另一种方法是(从字符串变量mystring
开始)
gen myst = subinstr(mystring, "-", " ", .)
assert inlist(wordcount(myst), 1, 2)
gen mynumeric = cond(word(myst, 2) == "", real(word(myst, 1)), (real(word(myst,1)) + real(word(myst, 2))/2)
这种方法适用于那些流利的正则表达式语法,但可以更容易地为其他人思考。