在DATA步的第一个语句,即读数据之前定义变量的属性,有这样几个优点:
定义变量的长度、格式,名称等属性,对新生成的变量而言,这是必须的。如果不定义新变量的长度,可能会造成变量取值截尾。这里只是说可能,偶尔偷懒也不是完全不可以,但要保证不能出错。
新生成的变量会出现在数据集的最前面,方便确认变量衍生过程是否正确。
数值型变量没有定义长度的说法,我们可以统一给字符型变量赋予一个合适的长度,并全部写在一个位置,这很大程序上带来了程序编写和更新的方便。
对长度大于200个字符的,我们在Log中显示Note。注意这里没有写成真正的"ERROR",这是为了防止在搜索Log错误时,把这条Note当成是Error。
对字符型变量去首尾空格常常是有必要的(例如,有的原始变量在录入时包括空格),尤其是数值型变量转换成字符型变量的时候。
CATX函数可以以指定的分隔符连接字符串或变量,如果所连接变量有变量为空,则不会出现多余的分隔符。
在SDTMIG 3.2版本,EPOCH、VISIT、TAETORD等变量对某些domain来说是Permissable,但在新一版的SDTMIG 3.3中,可能就是一个标准变量了。所以在对数据做验证的时候,要明确所使用的各种文件版本。
OUTPUT语句用于输出数据。我们常规的DATA步没有使用OUTPUT语句也能产生数据集,是因为它默认输出的,如果要基于一定的条件而选择性的输出数据,那就要使用OUTPUT语句。OUTPUT语句的执行可以形象地理解为:前面的条件让合适的数据排在前面,后面的条件让合适的数据排在后面,变量值可能会一直RETAIN。在使用OUTPUT语句时要小心,各种意想不到的错误可能都会出现,还不好查出原因在哪里,为了防止可能出现的RETAIN或者其他错误,可以当变量每次重新赋值的时候,使之初始化为缺失值。
TRANWRD函数可以把字符串里的指定字符转换成另外一指定字符。
用法:TRANWRD(Source, From, To),Replace from character sting in source with to character string。语句TRANWRD(pct,’( ‘,’ (‘),把pct=“( 10.1%)”变成pct=“ (10.1%)”,也就是把括号里面的空格变到外面,这样一来数据紧密联系在一起了,还能保证括号右对齐。这里前面只有一个空格,如果是1.1%会有两个空格,那就再用一次TRANWRD函数。这样处理会使得TFL比较好看。
对数据TRANSPOSE后形成的变量易产生缺失值,可能出现某个变量在某些行有值,有些行为空,也就是缺失的。如果需要全部替换成0或者NA,可以用ARRAY一次性处理。
如果变量较少,可以用if var=. then var=0。
但如果变量较多,用array。
array zero{*} _numeric_;
do i=1 to dim(zero);
if zero{i}=. then zero{i}=0;
end;
*是种省略写法,’{}’,’()’均可,dim返回数据的维度,表示数据集中所有的数值型变量的个数。也可以把_numeric_替换成具体的变量。
对字符型变量,用法类似。
array char{*} _character_;
do i=1 to dim(char);
if missing(char(i)) then char(i)=’0’;
end;
OPTIONS SYMBOLGEN MPTINT MLOGIC;
SYMBOLGEN:在log中编译出宏变量的具体值,可以检查宏变量返回值的对错。
MPTINT:把编译出的宏变量值直接代入到程序中,形成一段完全的代码,用于检验整段程序运行是否正确。
MLOGIC:标识宏程序的开始和结束,可以用于区别MACRO和一般程序。
这三个选项是用于调试MACRO的,一般在项目的SETUP程序中就写进去,这样一来,可以看那些GLOBAL的MACRO在这个STUDY的适用性,另外,每个Team Member也可以测试自己的宏,省去了再加OPTIONS的麻烦。不建议在Individual程序中写类似于LIBNAME,OPTIONS之类的GLOBAL语句,全局性语言可以放在GLOBAL程序中,如SETUP.SAS。
DATA步中可用IF…THEN…来做条件判断,SQL语句中可以用CASE…WHEN。
如果是创建一个表(SQL语言中分别叫表、行、列,对应SAS中的数据集、观测、变量),结果就不会OUTPUT出来,那就不用加NOPRINT语句,CASE前面有逗号。
如果语句较复杂,WHEN后面可以根据运算结果来指定相应的值,简单的语句则直接用CASE变量。用ELSE语句来表示判断结束,而且不能是空的ELSE语句(DATA步中的SELECT WHEN可用空的OTHERWISE结尾),如果条件已经选择完毕,用ELSE+空格表示结束字符型变量的定义,ELSE +点表示结束数值型变量的定义,或者用ELSE表示最后一个条件。如果生成的是字符型变量,建义定义一个长度,以防TRUNCATED。
只要涉及到循环,最好缩进,让程序美观易读。
我们在写Specification的时候,尽量让它更美观,更直接的呈现在User那边,像下图这种,你打开Excel,拖到这个变量的时候,它占满了整个Excel Sheet,这样看起来很不方便。
我们在进行各种Task时,铭记一点,你待它如初恋,它待你如真爱!
假设要以这样一种缩进方式来呈现数据。
有的朋友使用空格来对数据进行缩进,以及获得相应的层次感,包括各种Format,Label,Term,当然这也是可以的,在最后的表格中,把鼠标放在适当位置,指针显示有空格。其实,我们可以使用RTF语句,比如下句完成按两个字符一级的缩进。
Term太长可能会Wrap到下一行。
如果使用空格,下一行的数据会直接顶格,没有体现出数据的层级。
使用RTF会自动地排在相应等级,但还是个有问题,下一行的数据到底是另外一个Term,还是上一个Carry下来的呢?像这里CMCECOD就有两行了,但其实都是同一个CMDECOD,我们再加点语句以示区分:如果数据移到下一行,缩进一个空格。
如下图所示,表格更好看了。
在做Table的时候,有朋友喜欢以这种方式插入一个空行,以分隔不同部分的内容,针对不具有扩展性的内容是可行的。但如果某些Summary Table是by Category、by Visit、by Name,且并不清楚要空多少行时,可以在REPORT中使用COMPUTE语句,这样空行不会成为数据集的一部分,同时为OUTPUT服务。
如果有想写文章的朋友,请联系我,我需要你,内容不限!