我有一组数据集,其中某些变量已被定义为长度> 2000个字符。我想要做的是创建一个标识这些变量的宏,然后创建一组新变量来保存这些值。
在基本代码中执行此操作将类似于:
data new_dset;
set old_dset:
length colnam1 colnam2 colnam3 2000.;
colnam1 = substr(long_column,1,2000);
colnam2 = substr(long_column,2001,2000);
run;
我可以将变量名和长度列表构建为一组宏变量,但我不知道如何从宏变量创建新变量。
我认为它看起来像是:
%macro split;
data new_dset;
set old_dset;
%do i = 1%to &num_cols;
if &&collen&i > 2000 then do;
&&colnam&i 1 = substr(&&colnam&i,1,2000);
end;
%en;
run;
%mend;
我知道这不起作用,但这就是我的想法。
如果有人可以帮我们解决问题,我将非常感激。
由于
布赖恩
答案 0 :(得分:1)
您的宏不需要是整个数据步骤。在这种情况下,确切地查看您正在复制的内容然后根据它编写宏是有帮助的。
所以你的代码是:
data new_dset;
set old_dset:
length colnam1 colnam2 colnam3 2000.;
colnam1 = substr(long_column,1,2000);
colnam2 = substr(long_column,2001,2000);
run;
你的宏确实需要:
length colnam1 colnam2 colnam3 2000.;
colnam1 = substr(long_column,1,2000);
colnam2 = substr(long_column,2001,2000);
所以你能做的就是把它放在一个宏中:
%macro split(colname=);
length &colname._1 &colname._2 $2000;
&colname._1 = substr(&colname.,1,2000);
&colname._2 = substr(&colname.,2001,4000);
%mend;
然后生成一个调用列表:
proc sql;
select cats('%split(colname=',name,')') into :calllist separated by ' '
from dictionary.columns
where libname = 'WORK' and memname='MYDATASET'
and length > 2000;
quit;
然后你运行它们:
data new_dset;
set old_dset;
&calllist;
run;
现在你已经完成了:)& calllist包含%split(colname)调用的列表。如果您可能需要2个以上的变量(即长度> 4000),您可能需要添加一个新参数“length”;或者如果您使用的是9.2或更新版本,则只需使用SUBPAD而不是SUBSTR,并为每个外部变量生成所有三个变量。