从程序员到数据科学家:SAS 编程基础 (07)- 常量与变量


认识世界的第一步是正确命名各种实体,在SAS 程序中,标识符是就是用于命名编程语言实体的名称。常用的标识符分为变量名和成员名两大类,包括常量名、变量名、数组名、函数名、逻辑库和文件引用名称,成员和数据集名称等等。标识符名称只能以字母或下划线开头,由字母、下划线或者数字组成。大部分标识符名称(比如数据集名和变量名)遵循长度不得超过32字节规则,除了:

1.  逻辑库引用/文件引用libref/fileref)名称最长为8字节

2.  函数/调用例程Function/CALL Routines)函数名最长为16字节 

另外,关于长度限制还有如下一些特例:

  • 格式名长度限制:字符/数值型输出格式名称最长为31/32字节;字符/数值型输入格式名称最长为30/31字节。
  • 数据集描述标签最长为32字节,而数据列描述标签最长为256字节。

在下面的例子中,libref 标识符最长只能 个字节。而数据集(表)和变量(列)最长为 32个字节。如果你增加一个字符则会报编译错。

libname lib45678 "c:\temp";  /*逻辑库名最长8字节*/

data lib45678.tab45678901234567890123456789012;/*数据集名最长 32 */

    col45678901234567890123456789012=10/*数据列(变量名)最长 32 */

    a_=10;

    _a=10

run;

在下面的例子中,fileref 标识符最长只能8个字符。样例代码演示了在如何将文本写入外部文件 c:\test.log

/*fileref 最长只能8字节*/

filename file5678 'c:\test.log' encoding="utf-8";

data _null_

   file file5678;

   put "Hello World!";

run;

SAS 有两个系统选项可用于控制变量名和成员名的命名规则:

  • VALIDVARNAME:指定SAS会话中可以创建和处理的有效的SAS变量名,有三个参数可选:V7 | UPCASE | ANY,默认值为上面讲到的传统命名规则 V7UPCASE就是在V7命名规则之上,变量名还必须是大写的(用于早期SAS版本);如果变量命名中要包含国家语言字符(如中文),必须指定为 ANY。用法如下:

options validvarname=ANY;

即使启用了 ANY 变量命名规则,变量名仍然不能与系统自动变量 _N__ERROR_ 或者系统变量列表 _NUMERIC__CHARACTER_  _ALL_ 相冲突。

  • VALIDMEMNAME:指定有效的SAS成员名,成员包括SAS数据集、SAS 数据视图、SAS目录、SAS索引及 SAS Item stores 等。有2个参数可选:COMPATIBLE | EXTEND,默认值为 COMPATIBLE;如果成员命名中要包含国家语言字符(如中文)或除了 / \ * ? " < > | : - 之外的特殊字符,必须指定为 EXTEND。用法如下:

options validmemname=EXTEND;

如果启用了这种扩展的命名规则,我们就可以在 SAS 里使用非英文的标识符来命名数据集或者数据集中的变量(即列名)。另外即使启用了EXTEND成员命名规则,命名仍然不得以英文句号开头;对于SPDE引擎,其名则不得包含英文句号且不能以美元符 $ 开头。简单例子如下:

/*逻辑库名最长8字节*/

libname lib45678 "c:\temp";

/*需要 options validmemname=extend; 否则编译错*/

data lib45678."中央人民政府数据库"n; 

    /*需要 options validvarname=any; 否则编译错*/

"中央人民政府变量名"n=10;          

run;

proc contents;run;

你可以在 SAS 中使用如下语句查询特定系统选项的设置:

proc options option=(validvarname validmemname);

run;

常量与变量

 SAS 语言DATA步中,可以在表达式中直接定义一个数值型或字符型常量。比如:

  • 数值型:2553.14159261.25E-10
  • 字符型:'Hello World'"HELLO WORLD""张三"

SAS 数值型变量和字符型变量默认长度都是8个字节,其中数值型变量可指定任何 3-8 字节之间的任何长度(Linux/Windows最小长度为3,而不常见的IBM z/OS 平台上最小为2字节),而字符型则可指定 1-32767 字节的任何长度。变量的类型和长度在SAS中可以使用下面三种方式之一显式指定:LENGTH 语句,ATTRIB 语句或者 FORMAT 语句(仅对字符型未指定长度时有效);其中 ATTRIB语句可以同时为多个变量指定类型和长度,而FORMAT则在指定类型和长度时也指定了输出格式信息。比如:

data MyData;

    /*数值型 2-8*/

    length n1 8;

    attrib n2 length=8;

    format n3 8.;

    /*字符型 1-32767*/

    length c1 $ 8;

    attrib c2 length=$8;

    format c3 $8.;

run;

proc contents;run;

SAS作为一种数据处理语言,需要经常处理没有观测到的数值,称为缺失值。数值型缺失值用单个小数点符号 表示,字符型缺失值使用单个空格字符 表示。

data _null_;

    missingnum=.;   *指定数值型缺失值;

    missingstr=' '*指定字符型缺失值;

call missing(missingnum, missingstr);
*使用 CALL MISSING 例程来将变量设置为缺失值;

    nullstr="";      *对于字符型变量,传统的空字符也被当作缺失值看待;

    length dotstr $ 1*对于字符型变量,赋给 . 等价于赋给 ".";

    dotstr=.;  dotstr2='.';

    if dotstr=dotstr2 then put "dotstr is equal to dotstr2";

    *检测变量是否为缺失值;

    if missingnum=. then put "missingnum is missing";

    if missingstr=' ' then put "missingstr is missing";

    if nullstr=' ' then put "** nullstr is missing";

    *使用函数来检查缺失值;

    if missing(missingnum) then put "missingnum is missing";

    if missing(missingstr) then put "missingstr is missing";   

    if missing(dotstr) then put "dotstr is missing";

run;

系统输出:

dotstr is equal to dotstr2

missingnum is missing

missingstr is missing

** nullstr is missing

missingnum is missing

missingstr is missing

数值常量

  • 整数与双精度浮点数

数值型常量可以用整数、定点实数以及科学计数法实数表示。但在常量赋给某个变量的时候需要注意精度问题。默认情况下,没有精度丢失的最小和最大整数区间为十六位的整数:-9007199254740992 9007199254740992(十六进制:FFE0000000000000 – 20000000000000),超过此范围的整数赋值可能精度丢失。

你可以在机器上运行如下程序,对比不同的结果。

data _null_;  

    intc_min=-9007199254740992; intc_max= 9007199254740992

    put "Integer Constant: " intc_min 17.  " ~ " intc_max 17.;

    *区间内的数值;

    intc_min2= intc_min + 1; intc_max2= intc_max - 1

    put "Integer Constant: " intc_min2 17. " ~ " intc_max2 17.

    *区间外的数值:精度丢失...;

    intc_min2= intc_min - 1; intc_max2= intc_max + 1

    put "Integer Constant: " intc_min2 17. " ~ " intc_max2 17.;

    intc_min3=-9007199254740993; intc_max3= 9007199254740993

    put "Integer Constant: " intc_min3 17. " ~ " intc_max3 17.;

    *区间外的数值重新回到区间内;

    intc_min4= intc_min3+1; intc_max4= intc_max3-1

    put "Integer Constant: " intc_min4 17. " ~ " intc_max4 17.;

run;

系统输出:

Integer Constant: -9007199254740992 ~  9007199254740992

Integer Constant: -9007199254740991 ~  9007199254740991

Integer Constant: -9007199254740992 ~  9007199254740992

Integer Constant: -9007199254740992 ~  9007199254740992

Integer Constant: -9007199254740991 ~  9007199254740991

实数常量表达式支持除小数点外的11位有效数字(包括符号位);如果用科学计数法表示(比如 2.22507E-308),除小数点外的整个数字(包括尾数、EE后面的符号位、指数)的有效位为11位。SAS浮点数的表达范围为:2.22507E-308 1.797693E308HEX000FFFFE2E8159D1  7FEFFFFFD7B9609A)。

data _null_;  

    /*定点实数表示结果只支持11位有效数字精度(不包括小数点)*/

    x=123456789.012;            *结果是 123456789.01;

    y=0.12345678912;            *结果是 0.1234567891;

    put "X=" x  " Y=" y  ; 

    /*科学计数法表示:SAS 浮点数最小/最大值,除小数点外最长只能有11位有效数字;*/

    double_min= 2.22507E-308

    double_max= 1.797693E308

    put "double: " double_min  "~ " double_max ;

    double1=double_min / 2000000*等于0.00001E-309 约等于 0;

    double2=double_max + 1.0;      *表示超出范围还是最大的浮点数;

    put "double1=" double1  "double2=" double2;

    double1= 2.225071E-308;   *结果是 2.22507E-308;

    double2= 1.7976931E308;   *结果是 1.797693E308;  

    put "double1=" double1  "double2=" double2;

run;

  • 日期/时间/日期时间

日期/时间/日期时间类型是一种特殊的数值型其常量定义采用引号后面加dtdt来分别表示大小写均可SAS的日期时间数据定义与别的公司不同。比如:SAS  DateTime的定义是从公历19601100:00:00开始的秒数。而微软对于 DateTime 的定义则是从公历00011100:00:00开始的滴答数Ticks:一秒钟等于1千万个滴答数)。

下面的例子演示了如何利用日期常量,时间常量以及日期时间常量对变量进行赋值:

data _null_;

    d='02JAN1960'D;

    t='00:00:01'T;

    dt='01JAN1960 00:00:01'dt;

    put " d=" d date.;

    put " t=" t time.;

    put "dt=" dt datetime.;

    put "value=" d t dt;

run;

运行上面的代码,结果你会发现变量 dtdt 不指定格式时的输出值都等于1,但他们的语义不同:196012日,t 00:00:01,而 dt 196011日凌晨 00:00:01

 SAS 系统中,还可以使用 CONSTANT函数来返回数学常量,比如 PI, E, EULER欧拉常数等,但一般不推荐大量重复调用 CONSTANT函数来获得常数给变量赋值。

data _null_;

    pi=CONSTANT("PI");

    e=CONSTANT("E");

    euler=CONSTANT('EULER');

    put "PI=" pi;

    put "E=" e;

    put "EULER=" euler;

    small=CONSTANT('SMALL');

    big=CONSTANT('BIG');       

    put "Double:" small "-" big;

run;

其中 SMALL BIG 分别返回当前机器上8字节所能表达的最小/最大双精度浮点数,即SAS 所能表示的双精度数范围的最小和最大值:2.22507E-308 1.797693E308。上面代码的输出为:

PI=3.1415926536

E=2.7182818285

EULER=0.5772156649

Double:2.22507E-308 -1.797693E308

字符常量

字符常量需要使用单引号或者双引号括起来,两者的区别是单引号字符串不会进行宏展开,而双引号中的字符串则会进行宏展开。比如:

data _null_;

    c="&sysver";

    put "SAS Version is " c;

    c2='&sysver';

    put "SAS Version is " c2;

run;

输出结果为:

SAS Version is 9.3

SAS Version is &sysver

注意:在 SAS 里,如果变量名字包含空格或者国家语言特定的字符,我们可以使用Name Literal来命名。其形式是一个引号括起来的空格或者国家语言字符的字符串常量,引号后面加上n(大小写皆可)。这种特殊的变量命名通常用于关系数据库的表名/列名SAS 变量名语句标签 (需要启用系统选项 VALIDVARNAME=ANY);或者SAS数据集SAS数据视图Item Store (需要启用系统选项 VALIDMEMNAME=EXTEND)的命名中,用于和外部系统交互而设计的。

*Name Literal 如果包含空格和国家语言字符,需要启用系统选项VALIDVARNAME=ANY;

*否则会报告语法错误;

options validvarname=ANY;

data _null_;  

    pi=3.1415926;

    c="PI"; c2="pi"n;

    put  c "=" c2; 

    "var 1"n = 100;

    put "var 1=" "var 1"n

    "变量1"n = 100;

    put "变量1=" "变量1"n

run;

系统输出如下:

PI =3.1415926

var 1=100

变量1=100

结语:任何编程都是从常量和变量开始,构建复杂的程序表达世界。SAS与传统编程语言不同之处在于为数据分析从根上定义了面向分析的数据类型和表达方式,从而注定了SAS编程人员的视角是基于一种更加高级、面向信息的数据表达,而不是传统的基于字节和位操作之上的数据结构和算法体系,尽管SAS依然保留了对字节和位层次的操作能力!

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值