[英]How to loop through a range of week status variables in SAS and pull status according to specific week given by other variable
[英]How to Loop Through Variable Formats and Rename In SAS
我有一个数据集,其中每列代表从 2018 年 2 月到 2025 年 12 月的不同月份、年份组合。这些列存储为字符,但我想将它们转换为数字。 目前,这些列被命名为“FEB_18”、“MAR_18”、“NOV_19”、“JUL_22”等。
我想创建一个循环,获取每个变量并将其转换为数字。 最初,我使用了以下代码,但这会为每次迭代创建一个新数据集。
%let months = JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC;
%MACRO DOIT(Peak=);
%do i= 1 %to %sysfunc(countw(&Name.));
%let Name2 = %scan(&months., &i.);
%do j = 18 %to 25;
proc sql;
create table ppl as
select
input(Label, Best12.) - 21916 as Contract format MMDDYY10., /* Excel to SAS Dates*/
input(&Name2._&j., Best12.) as _&Name2._&j.
from Transposed_&Peak.;
%end;
%end;
quit;
%mend DOIT;
%DOIT(Peak = On);
提前致谢!
CONTENTS
过程将使数据集的元数据(列名、类型、列号等)可用作数据。 从该数据中,您可以构建执行转换所需的语句
例子:
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.