SAS编程

246:SAS XPT V8 format生成

2023-07-08  本文已影响0人  林芷文的日常碎碎念

相信我,今天这篇文章你们以后一定用的到,先点赞收藏加关注,嘿嘿嘿!
现在不少申办方要求SAS数据集以XPT V8的格式传输,有时候也不一定用于注册递交,可能是用于其他用途。而且在《药物临床试验数据递交指导原则》里面建议采用XPT第5版本(简称XPT V5)或以上版本作为数据递交格式。也就是说,你可以以XPT V8的格式递交数据。

image.png

我们做SDTM比如说变量的长度限制在8以内,然后值超过200的时候要拆分,一部分原因就是因为XPT V5的限制。如今申办方要求XPT V8的格式越来越多,我觉得一部分原因就是不用考虑这些限制,要不然还得拼接来拼接去的,麻烦死掉。我记得以前做SDTM的时候,PEORRES超过了200,当时项目比较急,经理直接说不用拆分了,是多少就是多少,不知道是不是出于这个原因。

那么,如何将我们的SAS数据集转换成XPT V8的格式呢,SAS官方提供了一个宏,叫做%loc2xpt,废话先不多说,直接看代码转换XPT V8

libname raw "D:\Practice";   /*SAS数据集存放的路径*/
%let rawdir=D:\Practice2;    /*输出XPT 的路径*/

data raw.datset1;
    set sashelp.class;
    LBORRESU8="变量长度我超过8了,嘿嘿";
run;

data raw.datset2;
    set sashelp.cars;
    VARLENGTH="我们做SDTM比如说变量的长度限制在8以内,然后值超过200的时候要拆分,一部分原因就是因为XPT V5的限制。如今申办方要求XPT V8的格式越来越多,我觉得一部分原因就是不用考虑这些限制,要不然还得拼接来拼接去的,麻烦死掉。";
run;


data raw.datset3;
    set sashelp.class;
run;



proc sql;
   create table sdtmDomains as
      select libname
            ,memname
      from dictionary.tables
         where libname eq 'RAW'
      order by memname;
quit;

data _null_;
   set sdtmDomains end=eof;
   call symput('domain_' || strip(put(_n_,2.))
              ,strip(lowcase(memname))
              );
   if eof then 
      call symput('domainCnt',strip(put(_n_,2.)));

run;
%put &domainCnt;


*单个数据集;
%macro xpt;
   %do idx=1 %to &domainCnt;
   filename xptfile "&rawdir\&&domain_&idx...xpt";
      %loc2xpt(libref=raw     /*存放RAW数据集的SAS逻辑库*/
              ,memlist=&&domain_&idx    /*指定那个要转换的SAS数据集*/
              ,filespec=xptfile,FORMAT=V8    /*filespec指定你要输出XPT的路径 format指定V5还是V8*/
              );
   %end;
%mend xpt;
%xpt

说实话,SAS官方上的描述不清晰,举得例子也没有具体的路径,比如这个libref=raw,
我第一转换XPT,然后把XPT转换成SAS数据集的时候(检查,避免发给申办方的是空的XPT,大家工作中最好多重保险一下),发现总是报错,后来才发现是我的libref=指定错了,我写的是输出XPT的逻辑库,但是这个选项其实是指定你要把哪个逻辑库里的SAS数据集转换成XPT,其他的选项你们可以看我的程序的注释,别搞错了!!!


image.png

还有一种方法是看你导出的XPT的大小,比如上次我导出的XPT大小都是1KB,那肯定是没有导出成功,你想想怎么可能一点大小都没有,所以也可以通过这个判断。

image.png

遗憾的是,我在SAS官网上没有找到类似proc contents能够直接查看数据集属性的语句来查看XPT的版本,比如用proc contents我们能够查看SAS数据集的编码等信息。
proc contents data=sashelp.class;
run;

image.png

libname raw2 "D:\Practice2";   
%let rawdir2=D:\Practice2;    




%macro xptdat;
   %do idx=1 %to &domainCnt;
   filename xlocfile "&rawdir2\&&domain_&idx...xpt";
      %xpt2loc(libref=raw2       /*输出SAS数据集的地方*/
              ,memlist=&&domain_&idx
              ,filespec=xlocfile    /*存放XPT的地方*/
              );
   %end;
%mend xptdat;
%xptdat

数据集成功导出,我们可以打开看一下,变量长度没有发生截断,说明是成功的!


image.png image.png

data _null_; 
    infile 'D:\Practice2\datset3.xpt' recfm=f lrecl=80; 
    input; list; 
run;

还有一种方法是通过下面的这种方法,但是我不确定对不对,log里面会显示这个V8,

image.png

但是如果我用V5的XPT,就不会显示这个,


image.png

具体的你们可以参考一下SAS官网上的文件,它有两个文件,一个是介绍V5的,一个是介绍V8的,我没心情看完。

《Record Layout of a SAS® Version 5 or 6 Data Set in SAS® Transport (Xport) Format》

《Record Layout for a SAS® Version 8 or 9 Data Set in SAS® Transport Format》

最后再讲一个,如果申办方要求将所有的SAS数据集导出成一个XPT文件呢?注意这时候千万不是将所有数据集set在一起然后导出成XPT,我们只需要将do循环取消,然后将memlist=all改成这样就好了!

libname all "&rawdir";
*所有数据集的合并;
%macro xptall;
   filename xptfile "&rawdir\xpt\ALLDATASET.xpt";
      %loc2xpt(libref=raw
              ,memlist=_all_
              ,filespec=xptfile,FORMAT=V8 
              );

%mend xptall;
%xptall

然后用%xptloc导出成SAS数据集的时候,它会自动分成原来有多少个SAS数据集就会输出多少个。

卒!

上一篇 下一篇

猜你喜欢

热点阅读