SAS XPT生产的2种方式:
1.proc cport 过程步,与之对应的是XPT生产SAS数据的方式proc cimport 。
2.建立Xport逻辑库的方式,然后将数据集Set进去,反之这种方式将生成的XPT中提取数据集提取出来,同样是通过Set的方式。
NOTE:这俩种方式不能混合用,比如proc cport生成的xpt不能用libname的方式set出来,libname 生成的xpt不能通过proc cimport提取出来。
01
proc cport
proc cimport
这种方式用途:解决SAS数据集以及format文件版本不兼容问题。此方式生成的XPT文件,并非是向FDA提交数据的XPT。(虽然同XPT,但是此XPT非彼XPT)。这种方式,我们通常是将逻辑库下的数据集与format全部放到一个XPT文件里面,对外发送(统计师,Sponsor等)。因为不同公司不同人使用的SAS版本可能不太一样,高版本的SAS可以打开低版本的SAS的数据集,但低版本的SAS数据集打不开高版本的数据集,format文件:只能同版本SAS打开同版本的SAS生成的format。
code
note:第5行(生成xpt),第8行(解压xpt)。第1、11行(option format小技巧)
02
Libname Xport
set statement
该方式生成XPT用途:向FDA提交数据集的XPT,一个数据集一个XPT文件。且该XPT双击可以通过SAS Universal Viewer打开。同时对需要生成的数据集是有要求的。
Q:你知道为什么SDTM、ADAM数据集为什么对变量名称(变量名称的长度不得超过8个字节),变量长度(变量长度不得超过200个字节),变量Label长度(变量Label的长度不超过40个字节),变量format(无format,原有format都会通过CD表变成对应的真正的值)都有要求么?
A:这一切的罪魁祸首就是Libname XPort 生成XPT数据集的限制,该方式建立的逻辑库引擎是V6版本的,我对V6的理解是SAS比较早期版本引擎。该引擎对变量等都有要求和限制。因此就导致SDTM与Adam对数据集的要求。小编写的Macro也是针对于这种方式。知道原理,其实很简单,就是一个循环。Macro以及写好,可直接使用。
Log:由于小编用的非标准集(SDTM/adam集)因此出现这样的error
宏码
%macro xpt_sas2xpt(SASLIB=,outfile=);
options nofmterr;
%let lib1=%upcase(&SASLIB.);
proc sql noprint;
select count(distinct memname) into: nn from dictionary.columns where libname="&lib1.";
select distinct memname into:mem1-:mem%left(&nn.) from dictionary.columns where libname="&lib1.";
quit;
%do i=1 %to &nn;
libname xportout xport "&outfile.&&mem&i...xpt" ;
data xportout.&&mem&i.;
set &lib1..&&mem&i.;
run;
%end;
%mend;
%macro xpt_xpt2sas(infile);
options nofmterr;
filename xcl_fil pipe "dir ""&infile.""*.xpt /b";
data getfile;
infile xcl_fil truncover;
input fname $char1000.;
put fname=;
run;
data getfile;
set getfile;
uf=find(fname,'.',-200);
ef=substr(fname,1,uf-1);
zf=compress(ef,'.');
keep zf fname;
run;
data _null_;
set getfile;
call symput('N'||compress(put(_n_,best.)),strip(fname));
call symput('M'||compress(put(_n_,best.)),strip(zf));
run;
%let dsid=%sysfunc(open(getfile));
%let nobs=%sysfunc(attrn(&dsid,nobs));
%let rc= %sysfunc(close(&dsid));
data _null_;
call symput("date",left(put("&sysdate"d,yymmdd10.)));
call symput("date1",left(compress(put("&sysdate"d,yymmdd10.),"-"," ")));
run;
proc delete data=work.getfile;quit;
data _null_;
NewDir=dcreate("&date1.","&infile.");
run;
libname MyWork "&infile.&date1.";
%do i=1 %to &nobs;
libname xportout xport "&infile.&&N&i." ;
data MyWork.&&M&i.;
set xportout.&&M&i.;
run;
%end;
libname MyWork clear;
libname xportout clear;
%mend;