昨日,《药物临床试验数据递交指导原则》(试行)版正式公布了,在小编阅读后,于是本文因时而生了。
变量长度要求
在满足V5格式XPT变量长度的同时,需要字符变量长度是整个项目中相同变量名真实长度的最大值。本文将分享一段SAS小程序,自动修改逻辑库下字符变量长度为真实长度的最大值。
代码语言:javascript复制
options nofmterr compress=yes validvarname=upcase ;
libname test "EData";
*计算 输入数据集的每个变量真实的最大长度;
%macro chk_var_len(inds);
%local libname memname;
%if &inds.= %then %do;
%put NOTE:plesce check your dataset name;
%return;
%end;
%if %length(%sysfunc(compress("&inds.","."))) ne %length(%sysfunc(compress("&inds.",""))) %then %do;
%let libname=%scan("&inds.",1,".");
%let memname=%scan("&inds.",2,".");
%end;
%else %do;
%let libname=WORK;
%let memname=&inds.;
%end;
proc sql noprint;
select strip("MAX(length(")||strip(NAME)||strip("))")||" as "||strip("len_")||strip(NAME) into:varlist separated by "," from sashelp.vcolumn
where libname=upcase("&libname.") and memname=upcase("&memname.") and type='char' ;
quit;
proc sql undo_policy=none;
create table tp1_&memname. as select distinct &varlist. from &inds. ;
quit;
proc transpose data=tp1_&memname. out=tp1_&memname. ;
var _all_;
run;
data tp1_&memname.;
set tp1_&memname.;
length domain var $200.;
domain=upcase("&memname.");
var=substr(_NAME_,5);
drop _NAME_;
run;
%mend;
%macro chklib_var_len(lib=);
*利用循环得到每个数据集 每个变量的最大长度 ;
proc sql noprint;
select count(distinct memname) into: nn from dictionary.columns where libname=upcase("&lib.");
select distinct memname into:mem1-:mem%left(&nn.) from dictionary.columns where libname=upcase("&lib.");
quit;
%do i=1 %to &nn;
%chk_var_len(inds=&lib..&&mem&i.)
%if &i=1 %then %do;
data temp1;
set tp1_&&mem&i.;
run;
%end;
%if &i.>1 %then %do;
data temp1;
set temp1 tp1_&&mem&i.;
run;
%end;
%end;
proc datasets lib=work memtype=data noprint;
delete tp1_:;
run;
quit;
*得到长度存入temp1数据集后;
proc contents data=&lib.._all_ out=_varstemp10(keep=LIBNAME memname NAME LABEL type Varnum length) DIRECTORY NOPRINT MEMTYPE=data CENTILES;
proc sort data=_varstemp10 out=_varstemp10 sortseq=linguistic(numeric_collation=on);by memname Varnum ;
run;
proc sql ;
*计算最大长度;
create table _varstemp11 as
select *,max(COL1) as newlen
from temp1 group by var;
*并入全部变量列表中;
create table _varstemp12 as
select LIBNAME,memname,strip(NAME)||" "||ifc(^missing(newlen),strip("$")||strip(put(newlen,8.))||strip('.'),strip(put(LENGTH,8.))||strip('.')) as final
from _varstemp10 as a
left join _varstemp11 as b
on a.memname =b.domain
and a.NAME =b.var
order by memname,Varnum;
quit;
*修改长度不用报警告;
options varlenchk=nowarn;
data _null_;
set _varstemp12;
length news fmt $20000.;
retain news fmt;
by memname notsorted;
if first.memname then do;news=strip(final);
if index(final,'$') then fmt=strip(final);
else fmt="";
end;
else do news=strip(news)||" "||strip(final);
if index(final,'$') then fmt=strip(fmt)||" "||strip(final);
end;
if last.memname then call execute("data "||memname||"; length "||strip(news)||
"; format "||strip(fmt)||
"; informat "||strip(fmt)||
";set "||strip(LIBNAME)||strip(".")||strip(memname)||strip(";run;"));
run;
proc datasets lib=work memtype=data noprint;
delete _varstemp:;
run;
quit;
%mend;
%chklib_var_len(lib=test);
SAS程序递交
5月份的征求意见稿中,“不包含外部程序调用,尤其应避免大型宏程序的嵌套”已经修改成了“避免外部(宏)程序调用”。所以,从字面意思来看还是可以使用宏程序的,也可以使用嵌套宏程序的,只是宏程序的代码需要放入当前程序内部,不能外部调用。递交程序代码需要txt格式,实现方法很多,小编实现的方法是SAS,喜欢其他方法实现的请忽略。参考小编历史文章(点击下方可跳转)。
SAS-批量修改.sas后缀成.txt
数据说明文件
一般我们习惯性的将数据说明文件写在Excel中,现在提出要求需要XML或PDF,从文档中先提到XML 后提到PDF,小编猜测更倾向于XML文件。XML文件大概类似于CDISC标准中的Define.XML。所以SAS程序员可能难以避免的需要研究一下Define.XML的样式。可参考小编历史文章(点击下方可跳转)。
深入解剖SDTM-Define.XML
SDTM-Define.XML自动化生成工具
Adam-Define.XML的自动化生成
业内的Define的制作大概都是采用P21这个软件来制作,不过目前该软件只支持Define 2.0。如果要做自己Define,最好还是需要了解一下CDISC标准中Define相关的知识及制作的原理。
其他可能用到的
大概还能用到SAS编程的地方也就是变量超过200个字符的拆分和XPT的转化等。XPT的转化程序SAS自带内置宏里面也是有的,不过感觉自带内置宏不太靠谱。建议大家还是使用SAS中xport引擎方式去生成。查看自带内置宏方法可见小编历史推文。
SAS-如何找出数据集超长变量及观测,并自动进行变量的拆分...
SAS-编程中的小技巧(十二)
程序下载
上面的部分程序也可到小编网站上进行下载,如下图路径。
工具推荐列表
Tools-医学编码平台上线啦