前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Macro-Output Query(Edit Check Macro)

Macro-Output Query(Edit Check Macro)

作者头像
Setup
发布2019-10-21 17:12:10
9440
发布2019-10-21 17:12:10
举报
文章被收录于专栏:SAS程序分享号号号

愉快的周末又要结束了,繁忙的周一也即将开始!小编今天给大家Share的一个Macro是关于临床数据清理中的一个实用性的Macro,SAS Edit Check Output Query. -- Setup

背景介绍

临床试验数据清洗

小编曾从事临床试验数据清洗编程的工作,

虽然跳槽换了title,但是暂时本质还是一样...后面应该会变。。。还是回到主题上来。

什么是数据清洗?

在临床试验中,对试验数据进行前期的清理与逻辑核查,一般在数据清洗完成后在进行数据库的Database Lock ,Lock后的DataSet在交由统计师以及相关的编程人员进行统计分析,出相应的TFL等。

清理的目的?

为了后期统计分析的效果与质量,不管是在CRO还是在药厂,一般都是会有专门的数据部门存在,负责数据的清理。今天这个Macro就是用来帮助数据清理的。

在说程序前,还是要说一个东西,DVP(Data Validation Plan,数据验证计划)是由数据部门的DM编写,里面的是对临床试验收集的数据点进行验证的规则及其描述,SAS Programmer/Database Designer会更具DVP来实现一条一条的Edit Check,Edit Check 又分Online 和offline俩种,由于今年EDC系统的更新换代,很多核查都以及Online了,对于Offline的核查多是paper的项目与一些Online实现不了的核查,通过Edit Check核查出来的东西叫做Query,回有DM反馈给研究者,再由研究者解答疑问或者反馈会正确的数据。

说了半天还没说这个Macro是干嘛的,这个Macro就是用来写Edit Check的,更加便捷的输出Query。


Macro可以干嘛

跨表单执行逻辑核查,自动抓取变量的值,统一输出样式,批量执行Edit Check等等。。(见下图Macro简单的使用描述)

Excel模板

执行Log

执行结果

看Code

小编也知道,Code排版肯定会很烂,不要着急,文章结尾会给大家附上百度网盘链接,可以直接下载Code与Template,程序也可以直接使用。。我好像太帅了~

%macroChkQueryOutput(CheckData=,ChkLib=,SubjidKey=,VisitKey=,PageKey=);

Optionsmsglevel=N nomprint nonotes;

%put ;

%put ;

%put 开始执行!;

%put ;

%put ;

/*获取待核查逻辑库下的变量并进行预处理找出包含Format的变量*/

Proc contentsdata=&ChkLib.._all_ Out=FMTData(keep=MEMNAME name FORMAT) noprint;run;

proc sortdata=FMTData out=FMTData nodupkey; by_all_;run;

data FMTData;/**/

set FMTData;

name=upcase(name);

ifmissing(FORMAT) or FORMAT='$' then delete;

FORMAT=cats(FORMAT,'.');

if FORMAT="YYMMDD." Then FORMAT="YYMMDD10.";

DName=cats(MEMNAME,'.',NAME);

Output=cats("put(",name,",",FORMAT,")");

DOutput=cats("{put(",Dname,",",FORMAT,")}");

run;

%let dsid=%sysfunc(open(FMTData));/*获取FMTData数据集的观测为替换变量做准备*/

%let FMT1=%sysfunc(attrn(&dsid,nobs));/*nobs为观测数*/

%let rc= %sysfunc(close(&dsid));

data _null_;

set FMTData;

call symput('FNM'||compress(put(_n_,best.)),strip(Dname));

call symput('FOM'||compress(put(_n_,best.)),strip(DOutput));

run;

/*预处理EC不规范*/

data &CheckData. &CheckData._e;

set &CheckData.;

Deugw=count(QUERY,'{');

Deugm=count(QUERY,'}');/*判断{}是否是成对出现以及QUERY中是否包含英文双引号*/

ifDeugw-Deugm^=0 then output &CheckData._e;

/* if count(QUERY,'"')>0 or Deugw-Deugm^=0 orcount(Description,'"')>0 thenoutput &CheckData._e;*/

else output&CheckData.;

drop Deugw Deugm;

run;

data _null_;

set&CheckData._e;

call symput('deug'||compress(put(_n_,best.)),strip(DVPCODE));

run;

%let dsid=%sysfunc(open(&CheckData._e));

%let nobs7=%sysfunc(attrn(&dsid,nobs));

%let rc= %sysfunc(close(&dsid));

proc deletedata=&CheckData._e;quit;

%do k=1%to &nobs7.;

%put EC中QUERY填写不规范的DVP:&&deug&k.(DVP中包含“{}”不是成对出现),请核实;

%put ;

%put ;

%end;

dataCheckData_1;

set &CheckData.;

Description=tranwrd(Description,'"', '""');

QUERY=tranwrd(QUERY,'"', '""');

Query=Cats('Cats("',QUERY,'")');

%do i=1%to &FMT1.;

QUERY=tranwrd(QUERY,"{&&FNM&i.}","&&FOM&i.");

%end;

QUERY=tranwrd(QUERY,"{", '",');

QUERY=tranwrd(QUERY,"}", ',"');

run;

proc sqlUNDO_POLICY=NONE;

create tableCheckData_1 as

selectdistinct *

from CheckData_1

;

quit;

data _null_;

setCheckData_1;

call symput('ChkMainDATA'||compress(put(_n_,best.)),strip(DOMAIN));/*创建宏变量:获取主数据集*/

call symput('ChkDvpCode'||compress(put(_n_,best.)),strip(DVPCODE));/*创建宏变量:获取DVP编号*/

call symput('ChkSEQ'||compress(put(_n_,best.)),strip(SEQ));/*创建宏变量:获取SEQ(针对同条DVP拆分多种情况)*/

call symput('ChkDesc'||compress(put(_n_,best.)),strip(Description));/*创建宏变量:获取DM给到的DVP描述*/

call symput('ChkCondt'||compress(put(_n_,best.)),strip(Condition));/*创建宏变量:获取核查条件*/

call symput('ChkQUERY'||compress(put(_n_,best.)),strip(QUERY));/*创建宏变量:获取输出QUERY描述部分*/

call symput('ChkOtherSet'||compress(put(_n_,best.)),strip(OtherSet));/*创建宏变量:获取垮表单数据集*/

run;

/*获取EC条数以便进行循环*/

%let dsid=%sysfunc(open(CheckData_1));

%let nobs1=%sysfunc(attrn(&dsid,nobs));

%let rc= %sysfunc(close(&dsid));

proc deletedata=work.CheckData_1 FMTDATA;quit;

%do i=1%to &nobs1.;/*建立循环:从第一条EC开始循环*/

%let CDataSet1=%sysfunc(compress(%qscan(&&ChkOtherSet&i.,1,' ')));

%let CDataSet2=%sysfunc(compress(%qscan(&&ChkOtherSet&i.,2,' ')));

%let CDataSet3=%sysfunc(compress(%qscan(&&ChkOtherSet&i.,3,' ')));

%let CDataSet4=%sysfunc(compress(%qscan(&&ChkOtherSet&i.,4,' ')));

%let CDataSet5=%sysfunc(compress(%qscan(&&ChkOtherSet&i.,5,' ')));

%let CDataSet6=%sysfunc(compress(%qscan(&&ChkOtherSet&i.,6,' ')));

proc copyin=&ChkLib. out=Work; select&&ChkMainDATA&i. &&ChkOtherSet&i. ;run;

proc sqlUNDO_POLICY=NONE;/*where语句核查情况*/

create tableChk_Shun as

select &&ChkMainDATA&i...&SubjidKey.,&&ChkMainDATA&i...&VisitKey. ,&&ChkMainDATA&i...&PageKey. ,

"&&ChkDvpCode&i." as DVP_CODE length=200,"&&ChkDesc&i." as DECL length=2000,&&ChkQUERY&i.as Query length=2000

from&&ChkMainDATA&i.

%if%length(&CDataSet1.)^=0%then%do;

full join&CDataSet1. on &&ChkMainDATA&i...&SubjidKey.=&CDataSet1..&SubjidKey.

%end;

%if%length(&CDataSet2.)^=0%then%do;

full join&CDataSet2. on &&ChkMainDATA&i...&SubjidKey.=&CDataSet2..&SubjidKey.

%end;

%if%length(&CDataSet3.)^=0%then%do;

full join&CDataSet3. on &&ChkMainDATA&i...&SubjidKey.=&CDataSet3..&SubjidKey.

%end;

%if%length(&CDataSet4.)^=0%then%do;

full join&CDataSet4. on &&ChkMainDATA&i...&SubjidKey.=&CDataSet4..&SubjidKey.

%end;

%if%length(&CDataSet5.)^=0%then%do;

full join&CDataSet5. on &&ChkMainDATA&i...&SubjidKey.=&CDataSet5..&SubjidKey.

%end;

%if%length(&CDataSet6.)^=0%then%do;

full join&CDataSet6. on &&ChkMainDATA&i...&SubjidKey.=&CDataSet6..&SubjidKey.

%end;

where &&ChkCondt&i.

;

quit;

dataCHK_DAI_&i.;

set Chk_Shun;

run;

proc deletedata=work.Chk_Shun &&ChkMainDATA&i. &&ChkOtherSet&i.;quit;/*删除过程中衍生数据集*/

%let dsid=%sysfunc(open(CHK_DAI_&i.));

%let nobs4=%sysfunc(attrn(&dsid,nobs));

%let rc= %sysfunc(close(&dsid));

%put DVPCODE=&&ChkDvpCode&i...&&ChkSEQ&i. 执行完毕! Run出Query条数:【&nobs4.】;

%end;

dataChk_Output;

set CHK_dai_1;

run;

proc deletedata=CHK_dai_1;quit;

%if &nobs1.>1%then%do;

%do i=2%to &nobs1.;

proc appendbase=Chk_Output data=CHK_dai_&i.;run;

proc delete data=work.CHK_dai_&i.;quit;

%end;

%end;

%let dsid=%sysfunc(open(Chk_Output));

%let nobs3=%sysfunc(attrn(&dsid,nobs));

%let rc= %sysfunc(close(&dsid));

%put ;

%put 总计 :执行EC核查条数:【&nobs1.】 RUN出QUERY条数:【&nobs3.】;

%put ;

;

%mend;

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SAS程序分享号号号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库一体机 TData
数据库一体机 TData 是融合了高性能计算、热插拔闪存、Infiniband 网络、RDMA 远程直接存取数据的数据库解决方案,为用户提供高可用、易扩展、高性能的数据库服务,适用于 OLAP、 OLTP 以及混合负载等各种应用场景下的极限性能需求,支持 Oracle、SQL Server、MySQL 和 PostgreSQL 等各种主流数据库。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档