我的列中包含带前导零的数字。有些数字在末尾有字母表,如(00054A)表示特定值。我需要删除前导零并用值替换字母表。有些字母有负值,当我使用函数(TRANSTRN / TRANWRD)替换时,只有连字符被替换,值看起来像(000123-)。在删除前导零之后,我希望此负号位于数字的前面。由于在需要替换的6-8个不同列上存在值为(-12到+12)的字母,因此如果用宏写入它会更好吗?我应该使用什么函数来删除前导零并用负值代替字母?
数据:
0830 4368 0000856A
0177 7520 0001299K
代码:
data text1;
infile "/location/file.txt";
input VariableX $1-4 VariableY $5-8 VariableC $9-16
run;
data text2;
set text1;
VariableC=TRANWRD(VariableC, 'A', '1');
VariableC=TRANWRD(VariableC, 'K', '-2');
run;
输出:
0830 4368 00008561
0177 7520 0001299-
预期产出:
0830 4368 8561
0177 7520 -12992
答案 0 :(得分:0)
data test;
input VariableC $ 10.;
posit =0;
if substr(VariableC,2,2) = "00" then do; <== not to process value with less than two trailing zero
x =1 ;
do while (x ^=0 );
posit +1;
x=find(VariableC,"0", posit ); <== find where is the last zero.
if ( x - posit ) > 1 then x =0; <== Avoid finding '0' between non-zero number
and the end of expression
end;
subNewVariableC = substr(VariableC, posit );
end;
if find( subNewVariableC, "A", -1 ) = 1 then
NewVariableC=TRANWRD( subNewVariableC, 'A', '1');
if find(subNewVariableC, "K",-1) = 1 then do;
NewVariableC=TRANWRD( subNewVariableC, 'K', '2');
NewVariableC = trim("-") !! trim(NewVariableC);
end;
drop posit x subNewVariableC VariableC;
datalines;
...
run;
它会做你所期望的。
与此同时,我正在寻找好的解决方案,以便我也可以学习......
答案 1 :(得分:0)
我的偏好是以格式存储每个字母的值(实际上是一个信息,因为它使代码更容易,但原理是相同的)。然后将其用作查找以将字母转换为数字。
我将多个功能合并为一行,这使得它很长,其逻辑如下
input
函数sign
函数返回-1表示负值,1表示正值,0表示0。为了避免乘以0,我已经添加了一个来制作这个1。希望这是有道理的,这是代码。
/* create lookup informat */
proc format;
invalue letter 'A' = 1
'K' = -2;
run;
/* dummy dataset */
data have;
input x $ y $ c$ :15.;
datalines;
0830 4368 0000856A
0177 7520 0001299K
;
run;
/* transformed values */
data want;
set have;
c1 = left(put(input(
cats( compress(c,,'kd'), /* keep numbers */
abs(input(compress(c,,'ka'),letter.))) /* keep letter, convert to number (without the sign) and append to numbers */
,best12.)
*ifn(input(compress(c,,'ka'),letter.)=0,1,sign(input(compress(c,,'ka'),letter.))) /* multiply by sign of letter lookup number (if 0 then multiply by 1) */
,best12.));
run;
答案 2 :(得分:0)
如果A和K是您需要注意的唯一场景,那么PRX功能可以按旧学期条款(如果......那样)提供:
/* dummy dataset */
data have;
input x $ y $ c$ :15.;
datalines;
0830 4368 0000856A
0177 7520 0001299K
;
run;
data want;
set have;
if strip(reverse(c)) =:'A' then
do;
c=prxchange('s/A$/1/',-1, trim(c)); /*if the last char is A, first replace A with 1*/
c=prxchange('s/^0*//',-1, trim(c)); /* Second replace the leading 0s with nothing*/
end;
else if strip(reverse(c)) =:'K' then
do;
c=prxchange('s/K$/2/',-1, trim(c)); /*If the last char is K, first replace K with 2*/
c=prxchange('s/^0*/-/',-1, trim(c)); /*second replace the leading 0s with -*/
end;
run;