正如京剧所说, 变量的类型一旦确定, 就不会再改变, log中提示的自动转换, 指的是变量的值在拿来用的时候类型变化了, 是值的类型变化了, 而不是变量本身的数据类型变化了.
比如b='200', a=b+b, 是原来字符型的'200'变为数字型的200, 而不是b由字符型变为数字型.
反过来比较好理解, 字符型变量的值, 能转成数字的, 就变成数字, 不能的就拉倒, 置为空值. 比如:
data test;
a='2e3';
b=a*1;
run;
a变成数字之后是2000, 所以能够实现自动转换. 当然如果a='k'的话是无法自动转为13的.
并且自动转换一般都比较精确, 特别是数字转字符, 人为转的话还得left trim一下
至于tekuaile例子中提到的例子, 涉及到变量的length的概念: length指的是sas储存某个变量所用的byte数, 对于字符型变量, 1个byte正好对应一个字符位置, 对于数字型变量则不是, 字符型变量的length范围是3-8, 越高则储存的越精确. 这在值类型变换中体现的比较明显.
data test;
length a $4.;
b=10000;
a=b;
run;
如果是要用left trim来给a赋值, 那么是很难赋值准确的. 这时候自动转换就体现出了优势.
tekuaile提到的例子中第二个put的结果中e的结果很有意思:
data test;
252 a=2001;
253 b='200';
254 c=a+b; /*b的值读取之后变为数字200,*/
255 d=a||b; /*a和b的值分别变为各自的字符型*/
256 e=b+d;
257 put a= b= c= d= e= ;
258 b=a;/*a的值变为字符型2e3*/
259 a=b;/*由于b的length限制,a的值变为2000*/
260 c=a+b;
261 d=a||b;/*由于连接符,ab的值都变为字符型,d的值为'20002e3'*/
262 e=b+d;/*因为算数运算, bd的值变为数字型, d的值变为数字型对应20002000*/
263 put a= b= c= d= e= ;
264 run;
继续讨论:
225 data b;
226 a=300;
227 b='20';
228 c=a||b+b||a;
229 run;
NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column).
228:6 228:8
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
228:3 228:7 228:11
由以上例子可以看出SAS进行值自动转换的大概特点:
1, 不以最终值的类型判断是否如何进行转换, 而是以某个符号为根据. 比如228行中根据+判断应该转为数字型, 又
根据||判定应该转为字符型.
2, ||和+同时存在, +优先, 先根据+判断加号前后的需要转换为字符, 也就是228行的6,8两个位置
然后根据||前后判断, b+b作为整体应为字符型, 则指出+的位置代指b+b运算的结果.
3,
|