在SAS中重复一个宏
我试图从下面的数据集(test2)中随机选择6个案例。必须按照ED、CCM、MAT、CAC的特定顺序选择案例。第一张通行证来自付款人1(P1),第二张通行证来自付款人2(P2),直到我总共收到6个案例。在每个度量类型中,首先选择随机数最低的情况。下面是我正在使用的宏,我希望能够由付款人重复在SAS中重复一个宏,sas,Sas,我试图从下面的数据集(test2)中随机选择6个案例。必须按照ED、CCM、MAT、CAC的特定顺序选择案例。第一张通行证来自付款人1(P1),第二张通行证来自付款人2(P2),直到我总共收到6个案例。在每个度量类型中,首先选择随机数最低的情况。下面是我正在使用的宏,我希望能够由付款人重复 ID Measure Payer 1439 CAC P1 1135 CCM P1 1736 ED P1 1737 MAT P1 1738 CCM P2 2351 ED P2 42
ID Measure Payer
1439 CAC P1
1135 CCM P1
1736 ED P1
1737 MAT P1
1738 CCM P2
2351 ED P2
4251 ED P1
DATA CAC CCM ED MAT;
set test2;
if measure = 'CAC' then output CAC;
else if measure = 'CCM' then output CCM;
else if measure = 'ED' then output ED;
else if measure = 'MAT' then output MAT;
RUN;
%MACRO select (dsn,num);
DATA &dsn;
set &dsn;
min_random=min(random);
RUN;
PROC SORT data=&dsn;
by Payer min_random;
RUN;
DATA &dsn;
set &dsn;
if _N_ le #
RUN;
%MEND select;
%SELECT(ED,1); %SELECT(CCM,1); %SELECT(MAT,1); %SELECT(CAC,1);
DATA sample1A;
set ED CCM MAT CAC;
RUN;
对于上述样本数据集,应使用6个案例的输出
1736 ED P1
1135 CCM P1
1737 MAT P1
1439 CAC P1
2351 ED P2
1738 CCM P2
我试图通过以下方式解决这个问题:
创建示例数据集
data test2;
infile datalines;
input ID Measure $ Payer $;
datalines;
1439 CAC P1
1135 CCM P1
1736 ED P1
1737 MAT P1
1738 CCM P2
2351 ED P2
4251 ED P1
;
run;
DATA CAC CCM ED MAT;
set test2;
if measure = 'CAC' then output CAC;
else if measure = 'CCM' then output CCM;
else if measure = 'ED' then output ED;
else if measure = 'MAT' then output MAT;
RUN;
%MACRO select (dsn,num);
DATA &dsn;
set &dsn;
min_random=ranuni(0);
RUN;
PROC SORT data=&dsn;
by Payer min_random;
RUN;
DATA &dsn;
set &dsn;
if _N_ le #
RUN;
proc append base=sample1A data=&dsn. force;
run;
%MEND select;
%macro loop;
%let inp=ED,CCM,MAT,CAC;
%let Num_of_records_to_extract=6;
%let Num_of_distinct_measure=4;
data _NULL_;
loop_count=int(&Num_of_records_to_extract./&Num_of_distinct_measure.);
semi_loop_count=mod(&Num_of_records_to_extract.,&Num_of_distinct_measure.);
call symputx("loop_count",loop_count);
call symputx("semi_loop_count",semi_loop_count);
run;
%if &loop_count. ge 1 %then %do;
%do i=1 %to &loop_count.;
%do j=1 %to 4;
%SELECT(%sysfunc(scan("&inp.",&j.,",")),1);
%end;
%end;
%end;
%if &semi_loop_count. ge 1 %then %do;
%do k=1 %to &semi_loop_count.;
%SELECT(%sysfunc(scan("&inp.",&k.,",")),1);
%end;
%end;
%mend;
%loop;
以下是我是如何做到这一点的
data test2;set test2;
ran=ranuni(123);
if measure='ED' then order=1;
if measure='CCM' then order=2;
if measure='MAT' then order=3;
if measure='CAC' then order=4;
run;
proc sort data= test2 out=P1;
by order payer ran;
where payer='P1';
run;
proc sort data= test2 out=P2;
by order payer ran;
where payer='P2';
run;
data S1 S3;set P1;
by order ran;
if first.order then output S1;else
output S3;
run;
data S2 S4;set P2;
by order ran;
if first.order then output S2;else
output S4;
run;
data sample;
set S1 S2 S3 S4;
run;
data sample;set sample (obs=6);
run;
也有不那么繁忙的方式。任何时候,只要可以通过组处理而不是宏循环来使用,就应该。在这种情况下,不需要将数据集分成很多部分来完成这项工作,如果数据集很大,就I/O而言,这是非常昂贵的 这是一个易于维护的解决方案。。。未测试:
%let SAMPLE_SIZE=6 ;
proc format ;
value $measure2order
'ED' = '1'
'CCM' = '2'
'MAT' = '3'
'CAC' = '4'
other = 'X'
; run;
*--- changing dataset name because I am tossing ---* ;
*--- records with unexpected values (or more ---* ;
*--- specifically, measures that are not ---* ;
*--- needed for this particular sample.) ---* ;
data SAMPLE
ODD_STUFF ;
set test2 ;
random=ranuni(123) ;
order=put(measure,$measure2order.) ;
if order='X' then output ODD_STUFF ;
else output SAMPLE ;
run;
proc sort data=SAMPLE ;
by payer order random ;
run;
data SAMPLE ;
set SAMPLE ;
by payer order random ;
if first.order ;
sample_count+1 ;
output ;
if sample_count GE &SAMPLE_SIZE then stop ;
drop random sample_count ;
run;
(顺便注意……这里的问题定义似乎有点古怪。假设您有一组好的数据,您的样本将为付款人=1的四个度量值中的每一个随机记录,为付款人=2的前两个度量值中的每一个随机记录。)什么是PMT_SRC_组?您是否执行了代码?最小随机=最小(随机);这不起作用,我将在这里放置另一个随机函数。我希望您理解,因为您使用的是随机数,所以您可能无法获得与您在此处发布的相同的输出,可能有两个1736 EDs或1135 CCM!!,只有ED、CCM、MAT、CAC的顺序是固定的。我确实执行了我的代码,最小值(随机)工作。我知道,由于我使用的是随机数,取决于种子,结果会有所不同。但我需要首先选择具有最低随机数的度量(类别)的记录,并需要通过付款人重复该过程,以获得总共6个随机案例。所有奇数通行证适用于付款人1,偶数通行证适用于付款人2。我没有修改您的逻辑。请参见下文。相同的情况在示例中不能重复