简体   繁体   English

如何为sas数据集中的每个观察结果执行宏?

[英]How can I perform a macro for each observation in sas data set?

Here is the macro code..... 这是宏代码.....

libname myfmt "&FBRMrootPath./Formats";
%macro CreateFormat(DSN,Label,Start,fmtname,type);
options mprint mlogic symbolgen;
%If &type='n' %then %do;
    proc sort data=&DSN out=Out; by &Label;
        Run;
    Data ctrl;
        set Out(rename=(&Label=label &Start=start )) end=last;
        retain fmtname &fmtname type &type;
        output;
    If last then do;
        hlo='O';
        label='*ERROR';
        output;
    End;
Run;
%End;
%Else  %do;
    proc sort data=&DSN out=Out; by &Start;
        Run;
    Data ctrl;
        set Out(rename=(&Start=label &Label=start )) end=last;
        retain fmtname &fmtname type &type;
        output;
    If last then do;
        hlo='O';
        label='*ERROR';
        output;
    End;
Run;
%End;
proc format library=myfmt cntlin=ctrl;
Run;
%Mend CreateFormat;

Here is the code for control data set through which above macro should run for each observation of the data set and the values of the observations are inputs for varibales in the macro.... 这是控制数据集的代码,对于每个数据集观察,以上宏应通过该代码运行,并且观察值是宏中变量的输入。

Data OPER.format_control;
Input DSN :$12.  Label :$15. Start :$15. fmtName :$8. type :$1. fmt_Startdt :mmddyy. fmt_Enddt :mmddyy.;
format fmt_Startdt fmt_Enddt date9.;
Datalines;
ssin.prd prd_nm prd_id mealnm n . 12/31/9999
ssin.prd prd_id prd_nm mealid c . 12/31/9999
ssin.fac fac_nm onesrc_fac_id fac1SRnm n . 12/31/9999
ssin.fac fac_nm D3_fac_id facD3nm n . 12/31/9999
ssin.fac onesrc_fac_id D3_fac_id facD31SR n . 12/31/9999
oper.wrkgrp wrkgrp_nm wrkgrp_id grpnm n . 12/31/9999
;

Something like this. 这样的事情。

proc sql;
select catx(',',cats('%CreateFormat(',DSN),Label,Start,fmtname,cats(type,')');
into :formcreatelist separated by ' '
from oper.format_control;
quit;

You may need to PUT some of your variables to get the format you want into the macro variable. 您可能需要输入一些变量以将所需的格式转换为宏变量。 I use the slightly cludgy cats/catx combo here, you could cats once with ',' added in a bunch of times also. 我在这里使用稍微笨拙的cats / catx组合,您也可以在添加猫猫一次后加上','。

You do have a limit here - around 20,000 characters total in a macro variable. 您在这里确实有限制-宏变量中总共约有20,000个字符。 If it's over that, you either have to use CALL EXECUTE (which has some quirky features) or you can put the macro call into a text file and %INCLUDE it. 如果超过此限制,则您必须使用CALL EXECUTE(具有一些古怪的功能),或者可以将宏调用放入文本文件并%INCLUDE。

There is a better way to do this rather than select ... into a macro variable. 有一种更好的方法,而不是选择...到宏变量中。 Use a temp file like this: 使用如下临时文件:

filename dyncode temp;

data _null_;
   file dyncode;
   set OPER.format_control;
   put '%createformat ....';
run;

%include dyncode;

filename dyncode clear;

This technique is not limited by the 32k length limitation on macro variables. 此技术不受宏变量的32k长度限制的限制。

Note that you should definitely use single quotes around the %createformat to prevent SAS from invoking the macro just prior to data step compilation. 请注意,您绝对应该在%createformat周围使用单引号,以防止SAS在数据步骤编译之前调用宏。 You want the macro to run when the %include runs. 您希望宏在%include运行时运行。

The above approach is analogous to call execute, but call execute is evil because it does not execute the macro and embedded data/proc code within the macro in the expected order. 上面的方法类似于调用执行,但是调用执行是有害的,因为它没有按预期的顺序执行宏和宏中嵌入的数据/过程代码。 Avoid call execute. 避免执行呼叫。

Finally, if you are running interactive SAS and using the technique there is a neat trick you can use to debug. 最后,如果您正在运行交互式SAS并使用该技术,则可以使用一个巧妙的技巧进行调试。 Comment out the last two lines of code -- the include and the filename clear. 注释掉最后两行代码-包括和清除文件名。 After you run the remaining code, enter the SAS command "fslist dyncode" in the command window. 运行其余代码后,在命令窗口中输入SAS命令“ fslist dyncode”。 This will pop up a notepad view on the dynamic code you just generated. 这将在您刚刚生成的动态代码上弹出一个记事本视图。 You can review it and make sure you got what you intended. 您可以对其进行检查,并确保您达到了预期。

Here's a call execute solution, just for completeness: 这是一个呼叫执行解决方案,仅出于完整性考虑:

data _null_;
  set OPER.format_control;
  call execute('%CreateFormat(' || DSN || ',' || Label || ',' || Start || ',' || fmtname || ',' || type || ');');
run;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM