RFPENDTC是SDTM人口学domain中的一个变量。表示这名受试者参与试验的结束日期/时间,也就是该受试者最后一次接触记录的时间。
因为涉及到非常多个时间变量的比较,而这些时间变量又分散在不同的数据集。所以我在面对RFPENDTC的时候会很头疼。今天参考了一个前辈的代码,用一个相对比较方便的方法做了出来,在简书上记录一下。本来想用OneNote记录,正好最近在练习使用OneNote,但是发现OneNote似乎没有插入代码块的功能,于是选择在简书上进行记录。
RFPENDTC最简单粗暴的做法是写一个宏,将每一个包含受试者信息的数据集中的日期/时间进行比较,再将所有数据集进行合并,选出最大的日期/时间。
而今天的方法其实也是对前一种方法的改进,主要是不用手动敲数据集的名字。
首先我们读取sashelp逻辑库中的vcolumn视图,该视图包含了逻辑库中数据集以及变量的相关信息。
data vcolumn;
set sashelp.vcolumn;
where upcase(libname)="RAW" and upcase(type)="CHAR" and find(upcase(name),"DAT") ne 0 and find(upcase(label),"日期") ne 0;
keep libname memname name;
proc sort;
by memname name;
run;
筛选出包含DAT,且标签中含有日期的变量。并按照数据集(memname)、变量名(name)进行排序。
随后我们将读取的变量信息读入一个新的数据集,并利用retain语句,将同一个数据集中不同的日期变量都放入memname2这个变量中。并将memname3变量赋值为我们需要的语句,即set(raw.xxx keep=xxx rename=(xxx=endat))的形式。
data dat;
length memname2 memname3 dat $200;
retain memname2 ;
set vcolumn;
by memname name;
if first.memname then memname2=strip(name);
else memname2=strip(memname2)||" "||strip(name);
dat=strip(name);
memname3="raw."||strip(memname)||"(keep=subjid "||strip(memname2)||" rename=("||strip(dat)||"=ENDAT))";
run;
随后我们依然利用retain语句,将memname3的值全部做进memname4中,此时,memname4的值就是我们最终需要的语句了。之后将memname4做成宏变量。最终利用set语句,将所有包含日期的变量做进同一个数据集中,使用排序,获取每名受试者的最晚日期。
data dat1;
set dat end=last;
length memname4 $4000.;
retain memname4;
if _N_=1 then memname4=memname3;
else MEMNAME4 = strip(MEMNAME4)||" "||strip(MEMNAME3);
if last;
run;
proc sql;
select memname4 into :dat from dat1;quit;
data dat_fin;
set &dat.;
where endat ne "";
time=input(endat,yymmdd10.);
rfpendtc=endat;
keep subjid rfpendtc time;
proc sort;
by subjid descending time;
proc sort nodupkey;
by subjid;
run;
第一次在简书上写记录,不知道之后的自己回过头来看这第一篇记录,会不会觉得很幼稚。毕业已经快要一年了,从事SAS程序员的工作也大半年了,却觉得自己进步很有限,大学时期养成的像是拖拉之类的坏习惯也还保留着。之前就一直想要在简书上记录一下自己的生活和工作,但是由于拖拉,一直到今天才写下第一篇。
希望自己能在简书上坚持记录自己的工作所学,以及自己生活中的进步。