相信我,今天這篇文章你們以后一定用的到,先點贊收藏加關(guān)注,嘿嘿嘿!
現(xiàn)在不少申辦方要求SAS數(shù)據(jù)集以XPT V8的格式傳輸,有時候也不一定用于注冊遞交,可能是用于其他用途。而且在《藥物臨床試驗數(shù)據(jù)遞交指導原則》里面建議采用XPT第5版本(簡稱XPT V5)或以上版本作為數(shù)據(jù)遞交格式。也就是說,你可以以XPT V8的格式遞交數(shù)據(jù)。

我們做SDTM比如說變量的長度限制在8以內(nèi),然后值超過200的時候要拆分,一部分原因就是因為XPT V5的限制。如今申辦方要求XPT V8的格式越來越多,我覺得一部分原因就是不用考慮這些限制,要不然還得拼接來拼接去的,麻煩死掉。我記得以前做SDTM的時候,PEORRES超過了200,當時項目比較急,經(jīng)理直接說不用拆分了,是多少就是多少,不知道是不是出于這個原因。
那么,如何將我們的SAS數(shù)據(jù)集轉(zhuǎn)換成XPT V8的格式呢,SAS官方提供了一個宏,叫做%loc2xpt,廢話先不多說,直接看代碼轉(zhuǎn)換XPT V8
libname raw "D:\Practice"; /*SAS數(shù)據(jù)集存放的路徑*/
%let rawdir=D:\Practice2; /*輸出XPT 的路徑*/
data raw.datset1;
set sashelp.class;
LBORRESU8="變量長度我超過8了,嘿嘿";
run;
data raw.datset2;
set sashelp.cars;
VARLENGTH="我們做SDTM比如說變量的長度限制在8以內(nèi),然后值超過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;
*單個數(shù)據(jù)集;
%macro xpt;
%do idx=1 %to &domainCnt;
filename xptfile "&rawdir\&&domain_&idx...xpt";
%loc2xpt(libref=raw /*存放RAW數(shù)據(jù)集的SAS邏輯庫*/
,memlist=&&domain_&idx /*指定那個要轉(zhuǎn)換的SAS數(shù)據(jù)集*/
,filespec=xptfile,FORMAT=V8 /*filespec指定你要輸出XPT的路徑 format指定V5還是V8*/
);
%end;
%mend xpt;
%xpt
說實話,SAS官方上的描述不清晰,舉得例子也沒有具體的路徑,比如這個libref=raw,
我第一轉(zhuǎn)換XPT,然后把XPT轉(zhuǎn)換成SAS數(shù)據(jù)集的時候(檢查,避免發(fā)給申辦方的是空的XPT,大家工作中最好多重保險一下),發(fā)現(xiàn)總是報錯,后來才發(fā)現(xiàn)是我的libref=指定錯了,我寫的是輸出XPT的邏輯庫,但是這個選項其實是指定你要把哪個邏輯庫里的SAS數(shù)據(jù)集轉(zhuǎn)換成XPT,其他的選項你們可以看我的程序的注釋,別搞錯了?。?!

還有一種方法是看你導出的XPT的大小,比如上次我導出的XPT大小都是1KB,那肯定是沒有導出成功,你想想怎么可能一點大小都沒有,所以也可以通過這個判斷。

遺憾的是,我在SAS官網(wǎng)上沒有找到類似proc contents能夠直接查看數(shù)據(jù)集屬性的語句來查看XPT的版本,比如用proc contents我們能夠查看SAS數(shù)據(jù)集的編碼等信息。
proc contents data=sashelp.class;
run;

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數(shù)據(jù)集的地方*/
,memlist=&&domain_&idx
,filespec=xlocfile /*存放XPT的地方*/
);
%end;
%mend xptdat;
%xptdat
數(shù)據(jù)集成功導出,我們可以打開看一下,變量長度沒有發(fā)生截斷,說明是成功的!


data _null_;
infile 'D:\Practice2\datset3.xpt' recfm=f lrecl=80;
input; list;
run;
還有一種方法是通過下面的這種方法,但是我不確定對不對,log里面會顯示這個V8,

但是如果我用V5的XPT,就不會顯示這個,

具體的你們可以參考一下SAS官網(wǎng)上的文件,它有兩個文件,一個是介紹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數(shù)據(jù)集導出成一個XPT文件呢?注意這時候千萬不是將所有數(shù)據(jù)集set在一起然后導出成XPT,我們只需要將do循環(huán)取消,然后將memlist=all改成這樣就好了!
libname all "&rawdir";
*所有數(shù)據(jù)集的合并;
%macro xptall;
filename xptfile "&rawdir\xpt\ALLDATASET.xpt";
%loc2xpt(libref=raw
,memlist=_all_
,filespec=xptfile,FORMAT=V8
);
%mend xptall;
%xptall
然后用%xptloc導出成SAS數(shù)據(jù)集的時候,它會自動分成原來有多少個SAS數(shù)據(jù)集就會輸出多少個。
卒!