首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SAS:以负值代替数字中的字母

SAS:以负值代替数字中的字母
EN

Stack Overflow用户
提问于 2015-06-27 19:10:46
回答 3查看 844关注 0票数 0

我有一个列,它有带前导零的数字。有些数字的末尾有字母表,如(00054A)表示特定值。我需要移除前导零并用值替换字母。有些字母有负值,当我使用函数(TRANSTRN/TRANWRD)替换时,只有连字符被替换,其值看起来类似于(000123-)。我希望在移除前导零后,这个负号在数字的前面。由于在6-8个不同的列上都有值为(-12到+12)的字母需要替换,所以用宏编写会更好吗?我应该使用什么函数来删除前导零并用负值代替字母?

数据:

代码语言:javascript
复制
0830 4368 0000856A

0177 7520 0001299K

代码:

代码语言:javascript
复制
    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;

输出:

代码语言:javascript
复制
   0830 4368 00008561
   0177 7520 0001299-

预期产出:

代码语言:javascript
复制
   0830 4368 8561
   0177 7520 -12992
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-06-29 13:54:44

如果A和K是您需要注意的唯一场景,则PRX函数可以按旧的学校术语提供它(如果.然后):

代码语言:javascript
复制
/* 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;
票数 0
EN

Stack Overflow用户

发布于 2015-06-29 03:57:43

代码语言:javascript
复制
   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;

它会做你期望的事。

同时,我正在寻找好的解决方案,以便我也可以学习.

票数 0
EN

Stack Overflow用户

发布于 2015-06-29 10:31:03

我倾向于以一种格式存储每个字母的值(实际上是一种in,因为它使代码更容易编写,但原则是相同的)。然后,它被用作查找,以将字母转换为数字。

我将多个函数组合成一行,这使得它非常长,其逻辑如下所示

  • 提取数字部分
  • 提取字母,转换为所需的数字(没有符号),并附加到已经提取的数字部分。
  • 使用input函数转换为数字类型
  • 将新创建的数字乘以字母查找值的符号。sign函数返回-1表示负值,1表示正值,0返回0。为了避免乘以0,我添加了一个片段来实现这个1。
  • 将此数字转换回字符值并左对齐以删除前导空格。

希望这有意义,这是密码。

代码语言:javascript
复制
/* 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;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31092540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档