Hi,
while performing the calculation in a datastep, I realized it became quickly diffcult to read, so I did the same using a macro step.
There must be an easier way I can't think of right now
%** Create test data;
DATA have;
length person $10 reqyear pm25_total2000-pm25_total2018 8;
array pm pm25_total2000-pm25_total2018;
do i=1 to 10;
person=cats('Person',put(i,best.));
do over pm;
pm=int(ranuni(0)*100);
end;
reqyear=2000 + floor((1+2018-2000)*rand("uniform"));
output;
end;
drop i;
RUN;
%** 1 - Using datastep;
DATA want;
set _NULL_;
RUN;
DATA _NULL_;
length pmname pm_start pm_end $32;
SET have;
ARRAY PMS pm25_total2000-pm25_total2018;
do i=1 to dim(PMS);
pmname =strip(upcase(vname(PMS[i])));
pm_start =strip(upcase(cats('pm25_total',put(reqyear-9,best.))));
pm_end =strip(upcase(cats('pm25_total',put(reqyear,best.))));
end;
put 'N' 'OTE:' Person= reqyear= pm_start= pm_end=;
if pm_start GE vname(PMS[1]) then do;
call execute('DATA _hlp; LENGTH mean 8 analyzed $70; SET have(FIRSTOBS='||strip(put(_N_,best.))||' OBS='||strip(put(_N_,best.))||');');
call execute('ARRAY pms_mean {*} '||strip(pm_start)||'--'||strip(pm_end)||';');
call execute('mean=mean(of pms_mean[*]); analyzed="mean of '||strip(pm_start)||'--'||strip(pm_end)||'";');
call execute('RUN;');
call execute('DATA want; SET want _hlp; RUN; PROC DATASETS lib=work nolist; delete _:; RUN;QUIT;');
end;
else do;
call execute('DATA _hlp; LENGTH mean 8 analyzed $70; SET have(FIRSTOBS='||strip(put(_N_,best.))||' OBS='||strip(put(_N_,best.))||');');
call execute('mean=.; analyzed="mean since '||strip(pm_start)||' not calculable";');
call execute('RUN;');
call execute('DATA want; SET want _hlp; RUN; PROC DATASETS lib=work nolist; delete _:; RUN;QUIT;');
end;
RUN;
%** 2 - Using Macro;
DATA want2;
set _NULL_;
RUN;
%macro calcMean(inDS=,outDS=,n=,Miss=,startVar=,endVar=);
%if &Miss. ne 1 %then %do;
DATA _hlp;
LENGTH mean 8 analyzed $70;
SET have(FIRSTOBS=&n. OBS=&n.);
ARRAY pms_mean {*} &startVar.--&endVar.;
mean=mean(of pms_mean[*]);
analyzed="Mean of &startVar.--&endVar.";
RUN;
%end;
%else %do;
DATA _hlp;
LENGTH mean 8 analyzed $70;
SET have(FIRSTOBS=&n. OBS=&n.);
mean=.;
analyzed="Mean since &startVar. not calculable";
RUN;
%end;
DATA &outDS.;
SET &outDS. _hlp;
RUN;
PROC DATASETS lib=work nolist; delete _:; RUN;QUIT;
%mend calcMean;
DATA _NULL_;
length pmname pm_start pm_end $32;
SET have;
ARRAY PMS pm25_total2000-pm25_total2018;
do i=1 to dim(PMS);
pmname =strip(upcase(vname(PMS[i])));
pm_start =strip(upcase(cats('pm25_total',put(reqyear-9,best.))));
pm_end =strip(upcase(cats('pm25_total',put(reqyear,best.))));
end;
put 'N' 'OTE:' Person= reqyear= pm_start= pm_end=;
if pm_start GE vname(PMS[1]) then
call execute('%nrstr(%calcMean(inDS=want,outDS=want2,n='||strip(put(_N_,best.))||' ,startVar='||strip(pm_start)||',endVar='||strip(pm_end)||');)');
else call execute('%nrstr(%calcMean(inDS=want,outDS=want2,n='||strip(put(_N_,best.))||',Miss=1,startVar='||strip(pm_start)||',endVar='||strip(pm_end)||');)');
RUN;
... View more