首页 > 解决方案 > SAS - 动态创建宏

问题描述

我想动态创建宏来查询事务数据集。我有一个包含一组参数(parameter_data)和事务数据(txs)的表。对于我的参数数据中的每一行,我想创建一个可以调用来查询数据的宏。

参数数据:

data parameter_data;
input macro_name $ parameter_name $ parameter_value $;
datalines;
A Person_ID 1
B TX_ID 2
;

交易数据:

data txns;
input Person_ID $ TX_ID $ TX_Amount $;
datalines;
John Sales 1123
Mary Acctng 34
John Sales 23
Mary Sales 2134
;

这里我尝试创建一个应该根据参数数据动态创建宏的宏。“内部宏”是从参数数据创建的宏。

%macro outerMacro;

/*loop through each row in the parameter table to get the detail of the macro we want to create*/
%DO ROW = 1 %To 2;
data _NULL_;
set parameter_data;
if _N_ = ROW then do;
    call symputx('parameter_name',parameter_name);
    call symputx('parameter_value',parameter_value);
    end;
run;

/*define inner macro parameters*/
%let macroName = myMacro; /*set the name of the macro we want to create*/
%let innerMacroStart = macro &macroName.; /*set the macro name to start the macro definition*/
%let innerMacroEnd = mend &macroName;

%&&innerMacroStart.; /*start the inner macro*/

    /*body of the macro*/
    data output;
    set txns;
    &&parameter_name = &&parameter_value; 
    /*so here effectively for the first row in the parameter table we are filtering where person_id = John*/
    run;

%&&innerMacroEnd.; /*end the inner macro*/

%mend outerMacro;

%&&outerMacroName.;

似乎 SAS 无法解析行 %innerMacroStart。任何帮助深表感谢。

谢谢!

标签: dynamicmacrossasnested

解决方案


我在每个代码块之前都添加了注释,但本质上是:

  1. 参数设置。
  2. 宏生成。
  3. %包括。
  4. 调用任何需要的宏。

我假设不超过 999 个参数观察值 - 这是由seq.

您可以检查文件“inner_macro.sas”以查看宏定义。

注意。尝试时,请确保使用自己的路径代替<your-path>(出现两次):

/* set up parameters */
data parameters;
   infile datalines dlm=',';

   input var      : $8.
         operator : $8.
         value    : $8.
   ;

   datalines;
name,eq,"John"
age,gt,12
weight,eq,0
;

/* read parameters and generate a macro definition for each obs, written to a file */
data _null_;
   file '<your-path>/inner_macro.sas';

   set parameters;

   seq = put(_n_,z3.);

   put '%macro inner_' seq ';';
   put '    where ' var operator value ';';
   put '%mend inner_' seq ';';
   put;
run;

/* %include (submits code in file) all of the macro definitions */
%include '<your-path>/inner_macro.sas';

options mprint;

/* invoke the macro with the required data sets */
data class1;
   set sashelp.class;
   %inner_001;
run;

data class2;
   set sashelp.class;
   %inner_002;
run;

data class3;
   set sashelp.class;
   %inner_003;
run;

推荐阅读