【问题标题】:Can I change the execution order of the CALL EXECUTE stack in SAS?我可以更改 SAS 中 CALL EXECUTE 堆栈的执行顺序吗?
【发布时间】:2009-09-04 14:36:14
【问题描述】:

我正在使用 SAS 9.1.3 在 DATA 步骤中调用宏,但该宏会生成 PROC REPORT 步骤,因此我使用 CALL EXECUTE 来调用它,生成所有这些 PROC REPORT 步骤,然后执行它们都在 DATA 步之后。

我正在使用一个数组,并且每次都会对该数组中的每个元素执行宏:

DATA macro_test;
  ARRAY questions[3] $ 32 ('question1' 'question2' 'question3');

  DO i=1 to 3;
    a_question = questions(i);
    CALL EXECUTE( "%report_by_question(a_question)" ); 
  end;

RUN;

问题是,报告输出(通常)向后输出 - 它会先打印 question3,然后是 2,然后是 1。

有没有办法修改 CALL EXECUTE 的执行顺序,以便我可以按顺序打印问题报告,还是它只是做自己的事情?

谢谢!

【问题讨论】:

    标签: sas sas-macro


    【解决方案1】:

    我假设您对 call execute() 行的意思更像这样:

     CALL EXECUTE( "%report_by_question(" || trim(left(a_question)) || ");" ); 
    

    使用测试宏,我得到一些这样的日志行,表明call execute()s 正在以正确的顺序发生。你有类似的东西吗?

    %macro report_by_question(a);
    data test_&a;
      do i=1 to 10000000;
        output;
      end;
    run;
    %mend;
    

    日志

    注意: CALL EXECUTE 生成的行。 1 + 数据 test_question1;做 i=1 到 10000000;输出;结尾;跑; 注意:数据集 WORK.TEST_QUESTION1 有 10000000 个观察值和 1 个变量。 注意:使用的 DATA 语句(总处理时间): 实时 6.14 秒 处理器时间 0.45 秒 1 + ; 2 + 数据 test_question2;做 i=1 到 10000000;输出;结尾;跑; 注意:数据集 WORK.TEST_QUESTION2 有 10000000 个观察值和 1 个变量。 注意:使用的 DATA 语句(总处理时间): 实时 3.87 秒 处理器时间 0.53 秒 2 + ; 3 + 数据 test_question3;做 i=1 到 10000000;输出;结尾;跑; 注意:数据集 WORK.TEST_QUESTION3 有 10000000 个观察值和 1 个变量。 注意:使用的 DATA 语句(总处理时间): 实时 3.12 秒 处理器时间 0.45 秒

    【讨论】:

    • 是的,哈哈,忘记了变量的整个连接;)所以是的,我在日志中得到了正确的步骤顺序,但是当它们开始在输出中吐出时,它们是看起来完全随机的顺序(我现在使用 5 个问题作为测试)。
    • OK - 我刚刚做了一个测试并做了 ODS 到 HTML,报告表格的顺序是正确的。我不明白为什么 ODS LISTING 会以不同的顺序将它们放在输出中。
    • CALL EXECUTE 工作正常且井然有序 - 只是结束这个问题!
    【解决方案2】:

    一个数据步被编译然后执行。 call execute(str); 将 str 推入输入队列,以便在数据步骤执行完 后将它们弹出。订单被保留,句号。

    但是,如果您将宏调用放在双引号字符串中,就像您在以下操作中所做的那样: 调用执行("%report(q)"); 然后在编译数据步骤时调用宏,甚至在数据步骤开始运行之前。

    如果你不想在编译时调用宏,那么要么用宏引用它,要么把它放在单引号字符串中。下面是一个例子。希望这会有所帮助。

    /* create a dataset with 1 var and 3 obs */
    data qs;
      input q $;
    cards;
    q1
    q2
    q3
    ;
    run;
    
    /* reporting macro -- a mockup */
    %macro report(q=);
      %put report for q=&q;
    %mend  report;
    
    /* call the reporting macro for each q */
    data _null_;  
      set qs;     
      macro = catx(q, '%report(q=', ')'); 
      call execute(macro);
    run;
    
    /* on log
    report for q=q1
    report for q=q2
    report for q=q3
    */
    
    
    /* to show what happens when the
       macro is invoked during the compile
       time */
    data _null_;
      call execute("%report(q=q1)");
      put "after call execute";
    run;
    /* on log
    1   data _null_;
    2     call execute("%report(q=q1)");
    report for q=q1
    3     put "after call execute";
    4   run;
    after call execute
    */
    

    【讨论】:

      【解决方案3】:

      我更喜欢使用宏语言来做所有与宏相关的事情。我想权衡是你的程序中散布着一些宏。但是,为了防止您的程序生成报告,只需将宏调用 (*%loopit;) 注释掉即可另外,您不必键入“question1”、“question2”、“question3”等!!!
      希望这对您有用!

      %macro report_by_question(input);
          %put "Question: " &input;
      %mend;
      
      %macro loopit;
          %do i=1 %to 3;
              %report_by_question("question&i.");
          %end;
      %mend loopit;
      %loopit;
      

      【讨论】:

      • 感谢您的洞察力,尚未在 SAS 中使用“宏语言”;)上面的示例只是为了解释我的问题而进行了简化。我正在使用 DATA 步骤循环遍历事物,并读取变量/问题数据集 - 不是硬编码这些东西,哈哈。
      猜你喜欢
      • 2014-09-23
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-25
      • 2023-02-02
      • 2022-11-17
      相关资源
      最近更新 更多