1

我正在尝试将字符串转换为数字变量,然后将每个字符的值求和以用作该字段的唯一标识符。例如,我想要 A=1、B=2、C=3.....X=24 Y=25 Z=26。假设我的字符串是“CAB”,所以在运行代码之后,我希望结果是一个中间数字列,其中 CAB 的值为 3 1 2,结果列将通过对字符串 3+1+2 求和得出= 6 并显示中间列的值,因此最终值为 6。

这是我用来将字符转换为数字的 sas 代码,但我需要有关结果列的帮助。

DATA CHAR_VALUE;
SET WORK.XYZ;
CHAR_2_NUM=TRANSLATE(MY_VAR_CHAR, '1 2 3 ...24 25 26', 'A B C ...X Y Z');
NUM_CHAR=INPUT(CHAR_2_NUM,32.);
RUN;

在此先感谢...感谢任何帮助或建议。-雷切尔

4

3 回答 3

2

RANK 将给出一个字符的 ASCII 数值;所以 A=65,B=66,Z=90,a=97,z=122。

所以这应该有效(如果你只想要大写的值 - 不是 a 的不同值而不是 A):

data test;
charval='CAB';
do _t=1 to length(Charval);
    numval=sum(numval,rank(char(upcase(charval),_t))-64);
end;
put _all_;
run;

另一种选择(基于下面的评论)是建立一个包含字母和值之间关系的信息。我的循环遍历每个字符 A 到 Z,然后您可以将每个字母的任何值作为标签(我只是放了 1、2、3、4 ......但 label= 会改变它)。

data fmts;
retain fmtname 'CHARNUM' type 'i';
do _t=65 to 90;
start=byte(_t); *the character, so byte(65)='A';
label=_t-64;    *the resulting number;
output;
end;
run;
proc format cntlin=fmts;
quit;

data test;
charval='CAB';
do _t=1 to length(Charval);
    numval=sum(numval,input(char(upcase(charval),_t),CHARNUM.));
end;
put _all_;
run;

最后,如果您希望能够在同一个数据步中构造它,您可以在哈希表中构造关系并查找结果。如果需要,我可以解释一下,尽管我希望看到一个更详细的示例,说明您在定义字母与其代码之间的关系方面想要做什么。

如果您需要查看中间值,您可以通过在循环中插入 CAT 函数来实现 - 我推荐 CATX:

data test;
charval='CAB';
format intermed $100.;
   do _t=1 to length(Charval);
        numval=sum(numval,input(char(upcase(charval),_t),CHARNUM.));
        intermed=catx('|',intermed,input(char(upcase(charval),_t),CHARNUM.)); *or the RANK portion from earlier;
    end;


put _all_;
run;

这会给你3|1|2,然后你可以通过 SCAN 进行数学运算:

do _t = 1 to countc(intermed,'|')+1;
  numval2 = sum(numval2,scan(intermed,_t,'|'));
end;
于 2012-12-07T16:56:52.460 回答
0

您尝试翻译的方法是一个很好的尝试,但它不会真正起作用。这是一个简单的解决方案:

DATA CHAR_VALUE;
  retain all_chars 'ABCDEFGHIJKLMMOPQRSTUVXXYZ';
  set XYZ;

  length CHAR_2_NUM $200;
  CHAR_2_NUM = ' ';
  NUM_CHAR = 0;

  do i=1 to length(MY_VAR_CHAR);
     if i=1 then CHAR_2_NUM = substr(MY_VAR_CHAR,i,1);
            else CHAR_2_NUM = trim(CHAR_2_NUM) || ' ' || substr(MY_VAR_CHAR,i,1);
     NUM_CHAR + index(all_chars,substr(MY_VAR_CHAR,i,1));
     end;
  drop i all_chars;
RUN;

这利用了变量中源变量的每个字符的索引位置all_chars对应于您所需的映射这一事实。

更新以创建您的CHAR_2_NUM变量,我在原始问题中忽略了它。

于 2012-12-07T18:55:30.680 回答
0

另一个简单的解决方案是基于collate函数:

要将一个名为MyNumbers(在 1 到 26 范围内)的变量转换为英文大写字符,可以使用:

collate(64 + MyNumbers, 64 + MyNumbers)

要获取小写字符,可以使用:

collate(96 + MyNumbers, 96 + MyNumbers)

这是一个简单的例子:

data _null_;
    do MyNumbers = 1 to 26;
          MyLettersUpper = collate(64 + MyNumbers, 64 + MyNumbers);
          MyLettersLower = collate(96 + MyNumbers, 96 + MyNumbers);
          put MyNumbers MyLettersUpper MyLettersLower;
    end;
run;

    1 A a
    2 B b
    3 C c
    4 D d
    5 E e
    6 F f
    7 G g
    8 H h
    9 I i
    10 J j
    11 K k
    12 L l
    13 M m
    14 N n
    15 O o
    16 P p
    17 Q q
    18 R r
    19 S s
    20 T t
    21 U u
    22 V v
    23 W w
    24 X x
    25 Y y
    26 Z z
    NOTE: DATA statement used (Total process time):
          real time           0.03 seconds
          cpu time            0.03 seconds
于 2019-05-25T22:58:56.807 回答