我正在尝试将字符串转换为数字变量,然后将每个字符的值相加以用作该字段的唯一标识符。 因此,例如,我希望A = 1,B = 2,C = 3 ...... X = 24 Y = 25 Z = 26。 假设我的字符串是“CAB”所以在运行代码之后我希望结果是一个数字的中间列,其中CAB的值为3 1 2,结果列将通过对字符串3 + 1 + 2求和得出= 6并显示intermideate列的值,因此最终值为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;
提前致谢...我感谢任何帮助或建议。 -rachel
答案 0 :(得分:2)
RANK将给出字符下面的ASCII数值;所以A = 65,B = 66,Z = 90,a = 97,z = 122。
所以这应该有效(如果你只想要大写的值 - 而不是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;
最后,如果您希望能够在相同的 datastep中构造它,您可以在哈希表中构建关系并查找结果。我可以解释一下,如果需要,虽然我想看一个更详细的例子,说明你想要在定义字母和代码之间的关系方面做些什么。
如果你需要查看中间值,可以通过在循环中插入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;
答案 1 :(得分: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
变量,我在原始问题中忽略了该变量。
答案 2 :(得分: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