前几天,看到有人问到SAS中关于format的一些问题,最近小编用format也用的比较多,所以啊,今天小编要分享的是SAS中关于format的应用,format在SAS编程中的应用是十分广泛的,也是SAS编程中不可或缺的一部分....那么就与小编一起来初识format...
先解决一个问题...
首先,我们来理解一下format,我一直把format当做数据展示的一个标签。我想这样理解应该没有什么太大问题,注意,这里是展示!而不是数据真实的自己,就像一个人,可以穿衣服一样,也可以换衣服,但改变不了自身的本质!这里衣服其实就相当是format,本质则是指自身!在SAS数据集的传输中,我们时常会遇到传输带有format的数据集,大部分人都是知道或遇到过数据集打不开的情况!这里小编就来解决一个关于format造成数据集打不开的的问题!
方法一:终极大招:可用下面的option控制,如果format文件丢失,或者format是跨版本SAS上,用这个选项就可以取消数据显示format.这样打开SAS数据集的时候,SAS就不会去找逻辑库下的那个小黄色的format文件.
代码语言:javascript复制options nofmterr;
方法二:如有format,而且是同版本上执行后的format文件,这个时候其实就更加简单了,可以用copy语句将format复制到work逻辑库下,这样其实就将format执行了一次!还有一种办法也是利用option来控制,看下方代码!
代码语言:javascript复制option fmtsearch=(raw);/*此处填写format所在的逻辑库名称*/
我想上面的俩个option选项应该已经在日常编程中够用了!但是呢,既然是100种format的应用,那么接下来随小编一起来看看关于format的一些其他的应用...
定义生成方式
既然说到format,那么就不得不说一下format的定义方式,SAS中比较常用的是使用proc format过程步来定义、生成format.在proc format过程步中比较常用的是value与invalue俩种插入方式。这个俩个有什么区别呢?接下来看几段代码与结果!
代码语言:javascript复制proc format library=work CNTLOUT=work.fmt;
invalue $ fmt_cdo "白细胞"="WBC" "红细胞"="RBC" "血小板计数"="PLAT"
"血红蛋白"="HGB" "中性粒细胞"="NEUT" "淋巴细胞"="NEUT";
value $ fmt_cdt "白细胞"="WBC" "红细胞"="RBC" "血小板计数"="PLAT"
"血红蛋白"="HGB" "中性粒细胞"="NEUT" "淋巴细胞"="NEUT";
run;
data temp1;
length LBTEST $40.;
input LBTEST ;
LBTESTCD1=input(LBTEST,$fmt_cdo30.);
LBTESTCD2=put(LBTEST,$fmt_cdt30.);
cards;
白细胞
红细胞
血小板计数
血红蛋白
中性粒细胞
淋巴细胞
;
run;
看着段代码!此处假设场景,在临床试验数据的转换过程中,有时需要根据TEST来衍生出CD值。上面代码中可以看到invalue、value定义了俩种format。这个时候其实是可以直接通过format来衍生与赋值一个新的变量的,见上面代码!这里input对应着invalue,put对应着value,俩种实现的效果是一样的!如果,我用input 的方式对应value 定义的结果会是怎么样的呢?接下来在来看一段代码!
这个时候,就会出现如上的情况,这里的理解,我觉得得意会了,我就不在细说了~接下来就看看定义format有什么需要注意的!在SAS中变量属性是分字符型与数值型的,format其实也是分类型的,字符型的format与数值型的format,也是需要对应使用的,否者就有问题,如上:我定义的是字符型的format,这里是在value/invalue后面加了一个$符号!用此种方式定义需要将等号俩边的值用引号引起来~接下来在来看看如何定义数值format...
代码语言:javascript复制proc format library=work CNTLOUT=work.fmt;
value rang 1-<20="正常" Low-<1="异常" 20< -High="异常无临床意义" .="MISS";
run;
data temp1;
input ORRES1 ;
LBTESTCD1=put(ORRES1,rang30.);
cards;
100
209
.
23
22
18
-1
;
run;
看这段代码!此处就是定义数值型的format,可以指定单个值,也可以指定范围内!运行后的结果!
细心的朋友肯定会发现,我定义的format名称后面都没有数值,却在put/input过程中,format是带有数字加.结尾的!这里的数字是声明一个长度的作用!
一个神奇的数据集
同样!细心的朋友也会发现一个问题,我proc format后面的参数是什么呢?有什么作用呢?首先第一个library的作用:我们执行完该过程步,SAS会产生一个黄黄色的小文件,这个小文件存储的逻辑位置,此时就受到了这个library=逻辑库名的影响。第二个cntlout参数:同样是在执行完该过程步后,SAS会将format的信息存储在一个数据集中!这里就要说到第三种解决数据传输中由于format的缺失而不开的情况,这儿是从源头解决,如果传输数据集的时候同时将一张存储了format的数据集一起传输,我们只需简单的语句,就可以再次生成、还原format!
这时候会生成一个数据这样的数据集,那么有一个这样的数据集,我们如何生成format文件呢,接下来在看一段代码!
代码语言:javascript复制proc format library=work CNTLIN=work.fmt;
run;
一种方式
既然,能够通过数据集直接转换并生成format,那么我们是不是可以就不用value的方式来进行定义format呢,如果用这种方式,我们需要写大量的引号、等于号等等!
奥,其实不需要写大量的,小编有时候图方便,会写一个简短的程序,将excel表中TEST、CD值复制粘贴到SAS中,运行一下,在复制粘贴到程序中!先来看看这种方式。
代码语言:javascript复制data aaa;
length aa1 bb1 $200.;
input aa1 $ bb1 $;
cc1=strip('"')||strip(aa1)||strip('"="')||strip(bb1)||strip('"');
cards;
白细胞 WBC
红细胞 RBC
血小板计数 PLAT
血红蛋白 HGB
中性粒细胞 NEUT
淋巴细胞 LYM
单核细胞 MONO
;
run;
proc sql noprint;
select cc1 into:varlist separated by " " from aaa ;
quit;
%put &varlist;
这种方式比较low,因为我们写程序的时候,经常有外部的excel文件会先做好这些东西,所以直接粘贴复制,利用一定规则连接起来,put到日志中,在粘贴复制到proc format过程步中,其实也很简单,但是有些繁琐,当然没有接下来我要说的方法简单,直接将excel导入SAS利用proc format过程步直接生成format文件!为啥上面的一段代码我要写在这里呢,尽管看似有点繁琐,小编觉得这是一种很好的思路,可能在这里有些繁琐,但是在其他的地方可能会有一些很好的应用的!那么接下来就来看看如何快捷的生成format...
首先,我们来观察一下数据集(利用proc format过程步生成的存储了FMT信息的数据集)的结构:为了的是做一个外部的模板,以后直接在模板里面填值,运行程序就自动调取数据生成format,以后如果有需要修改的,也不用在程序里面修改,直接在外部的excel模板里面修改,这样也能避免一些对特殊字符的处理措施!
这里需要注意的是:因为数据集变量很多,既然我们为了快捷,为了高效,为了图省事,当然是模板的变量越少越好咯,看我圈起来的变量,是关键变量,这个时候会问?那如何区分字符型和数值型的format呢?因为这个表里面还有一个type变量来区分,但是为了省事,我们可以在fmtname这个变量上做做手脚!
比如把数据集整成上面这个样子,我们可以用Excel来创建这几列,然后往里面填入值,在将excel导入SAS中,直接借用proc format过程步,也就是下面的这一段代码,可以直接生成format文件!当然制作数据集的方式很多,选用自己最合适的一种方式即可。小编是喜欢在外部借助Excel,这样修改起来比较方便,不用老是变动程序!可以增强程序的稳定性!
代码语言:javascript复制proc format library=work CNTLIN=work.temp2;
run;
在这里,我还要说一下,前面是说了value、invalue生成format的方式,那么这里生成的对应哪一个呢,小编一般用value多,基本不用invalue,小编觉得是TYPE变量来控制是哪一类的。接下来可以看一个图~如果有需求的话,也可以把TYPE变量保留下来,这样填入值的时候多填一下类型!如果没有TYPE变量,默认的是等效value方式定义的...
xpt解决format问题
关于format的问题!还有一种解决的办法,就是传输数据集的时候,我们将逻辑库下的数据集打包到XPT文件中,当然XPT的生成方式,小编历史推文有写到,俩种定义方式!至于是哪一种,我聪明的粉丝朋友们想必一看就知道,我这里就不说了:点击此处跳转到XPT生成方式
还想说点应用
前几天有朋友问我,如何让数字自动填充0,比如1,我想填充成01,这样的问题!这时候是可以用format来实现的..
代码语言:javascript复制data a;
input x y;
format x y z2.;
z=vvalue(x)||":"||vvalue(y);
cards;
1 3
2 3
12 32
;
run;
这里用到的format是z2. 如果3位补充0的话,那就是z3.这里的数字也是长度的意思....这里有一个vvalue的函数,也是一个很好的函数~如果对函数有兴趣,可见小编的历史文件函数篇,里面有提及到,这里就不在写了。
今天就这么多了,后续内容,敬请期待~