Чтобы избежать «жесткого кода», вам нужно использовать генерацию кода.
Сначала давайте выясним, какой код вы могли бы использовать для решения проблемы.Позже мы можем изучить способы генерации этого кода.
Вероятно, это проще всего сделать с помощью кода PROC SQL.SAS позволит вам ссылаться на значение MAX () переменной.Также обратите внимание, что SAS оценивает логические выражения как 1 (ИСТИНА) или 0 (ЛОЖЬ).Итак, вы просто хотите сгенерировать код вроде:
proc sql;
create table want as
select var1=max(var1) as var1
, var2=max(var2) as var2
from have
;
quit;
Для генерации кода вам необходим список переменных в вашем исходном наборе данных.Вы можете получить их с помощью PROC CONTENTS, но также и с таблицей метаданных (представление) DICTIONARY.COLUMNS (также доступной как SASHELP.VCOLUMN из-за пределов PROC SQL).
Если список переменных небольшой, вы можете сгенерироватькод в одну макропеременную.
proc sql noprint;
select catx(' ',cats(name,'=max(',name,')'),'as',name)
into :varlist separated by ','
from dictionary.columns
where libname='WORK' and memname='HAVE'
order by varnum
;
create table want as
select &varlist
from have
;
quit;
Максимальное количество символов, которое поместится в макропеременную, составляет 64 КБ.Так долго достаточно для примерно 2000 переменных с именами по 8 символов в каждой.
Вот немного более сложный способ, который использует PROC SUMMARY и шаг данных с временным массивом.На самом деле генерация кода не требуется.
%let dsin=sashelp.class(obs=10);
%let dsout=want;
%let varlist=_numeric_;
proc summary data=&dsin nway ;
var &varlist;
output out=summary(drop=_type_ _freq_) max= ;
run;
data &dsout;
if 0 then set &dsin;
array vars &varlist;
array max [10000] _temporary_;
if _n_=1 then do;
set summary ;
do _n_=1 to dim(vars);
max[_n_]=vars[_n_];
end;
end;
set &dsin;
do _n_=1 to dim(vars);
vars[_n_]=vars[_n_]=max[_n_];
end;
run;
Результаты:
Obs Name Sex Age Height Weight
1 Alfred M 0 1 1
2 Alice F 0 0 0
3 Barbara F 0 0 0
4 Carol F 0 0 0
5 Henry M 0 0 0
6 James M 0 0 0
7 Jane F 0 0 0
8 Janet F 1 0 1
9 Jeffrey M 0 0 0
10 John M 0 0 0