Процедура CONTENTS
сделает метаданные (имена столбцов, типы, номер столбца и т. Д. c) набора данных доступными в качестве данных. Из этих данных вы можете построить операторы, необходимые для выполнения преобразования
Пример:
X_feb_20 = input(feb_20, ?? best12.); * parse value in character variable into a numeric variable;
drop feb_20; * drop character variable from output data set;
rename x_feb_20 = feb_20; * change the name of the numeric variable back to the orginal;
Таким образом, задача состоит в том, чтобы сделать этот шаблон для всех столбцов символов в наборе данных, имя которого представляет собой <mon>_<yy>
. Тест
input('01'||transtrn(name,'_','20'),anydtdte.) is not null
идентифицирует такие имена столбцов.
Вот пример макроса, который будет выполнять работу по дому:
/*
* Fake some data to play with
*/
%macro month_columns(from_month=, to_month=);
%local index mon yy frstdate lastdate;
%let frstdate = %sysevalf("01&from_month"D);
%let lastdate = %sysevalf("01&to_month"D);
%do date = %sysevalf("01&from_month"D) %to %sysevalf("01&to_month"D);
%let date = %sysfunc(INTNX(MONTH,&date,0,E));
%sysfunc(putn(&date,MONNAME3))_%sysfunc(putn(&date,YEAR2.))
%end;
%mend;
data have;
call streaminit(123);
do stockid = 1 to 10;
array futures $12 %month_columns(from_month=FEB2020, to_month=DEC2025);
do over futures;
futures = put(rand('uniform',50) + stockid * sin(_i_/40), 12.5);
end;
output;
end;
run;
/*
* Chore macro
*/
%macro asnum_mon_yy_columns(data=, out=);
%local index;
proc contents noprint data=&data out=have_columns(keep=varnum name type);
run;
* SQLOBS will be number of rows (and thus names) that meet the date-like criteria ;
proc sql noprint;
select name into :name1-
from have_columns
where input('01'||transtrn(name,'_','20'),anydtdte.) is not null
and type = 2
order by varnum
;
quit;
data &out;
set &data;
%do index = 1 %to &sqlobs;
X_&&name&index = input(&&name&index,??best12.);
%end;
%if &sqlobs %then %do;
drop %do index = 1 %to &sqlobs;
&&name&index
%end;
;
rename %do index = 1 %to &sqlobs;
X_&&name&index = &&name&index
%end;
;
%end;
run;
%mend;
/*
* Invoke chore
*/
options mprint;
%asnum_mon_yy_columns(data=have, out=want)