SAS-新规试行下诞生的程序

2020-07-24 14:56:50 浏览数 (1)

昨日,《药物临床试验数据递交指导原则》(试行)版正式公布了,在小编阅读后,于是本文因时而生了。

变量长度要求

在满足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-医学编码平台上线啦

0 人点赞