【问题标题】:Is storing sas code in macro variables recommended?是否推荐将 sas 代码存储在宏变量中?
【发布时间】:2015-12-16 03:04:36
【问题描述】:

我必须修改一个 SAS 项目,其中有如下宏变量:

%let myDate = intnx('month',today(),-1);

以后……

data temp;
  a = &myDate;
run;

我倾向于改用%sysfunc

%let myDate = %sysfunc(intnx(month,%sysfunc(today()),-1));

但我想知道...这是偏好问题还是有充分的理由偏爱一种方法而不是另一种?

【问题讨论】:

    标签: macros sas


    【解决方案1】:

    对于非常大的数据集,您可能会发现在这个特定示例中,与定义一次宏变量并无限期地重复使用相比,为每一行调用一次 intnx 以获得相同的值会导致性能下降。

    Rob Penridge 已经证明,在这种情况下,开销可能可以忽略不计,但对于计算量更大的代码,显然情况并非总是如此。您的里程可能会有所不同。

    更一般地说,当您开始在宏变量中存储代码而不仅仅是常量时,您必须开始非常仔细地考虑某些事情:

    • 可能需要或不需要哪种宏引用(尤其是在 SAS/CONNECT 环境中,当您需要使用宏变量 rsubmit 代码块时)
    • 您的宏变量是否包含可能导致与其他代码块发生意外交互的分号或其他字符
    • 它是否包含在代码执行之前您不想解析的宏引用

    【讨论】:

    • 感谢您的深刻回答!
    • 我认为性能问题非常具有误导性,应该删除。在没有必要的情况下,它可能会引起关注。为每一行调用一个函数,即使在非常大的数据集上,也不会有明显的性能差异。
    • 只是为了量化性能问题——运行 1 亿次,需要 33 秒。如果您正在处理一个包含 1 亿行的数据集,那么数据步可能会花费比这更长的时间。额外的 30 秒将是杯水车薪。代码:data _null_; do i = 1 to 100*1000000; x = intnx('month',today(),-1); end; run;
    • @RobertPenr​​idge 感谢您的意见。及时更新。
    【解决方案2】:

    您还需要考虑时间问题。如果您使用%sysfunc(),则该函数会在创建宏变量时运行。如果您只是将函数调用存储在宏变量中,那么该函数实际上在数据步骤运行之前不会执行。在这种情况下,由于它正在调用 today() 函数,因此它将在每次观察时运行。如果您在当月最后一天的午夜之前开始数据步骤,您最终可能会在同一数据集中的不同观察中得到不同的 A 值。

    【讨论】:

    • 这应该是公认的答案,因为它是唯一解决产生正确结果问题的答案。
    • @RobertPenr​​idge 这是一个艰难的决定,因为 user667489 也有优点。如果可能的话,我会称之为平局! :)
    【解决方案3】:

    你说的是两个不同的东西。第一个带有 %LET 和 DATA 步骤的代码将创建一个宏变量 myDate 而不执行 INTNX 函数,但将创建一个具有列 a

    的表

    但是,第二个修改后的 %LET 语句实际上将创建一个宏变量,其值为执行的 INTNX 函数。

    所以,这实际上取决于业务需求是什么 -
    创建表格

    创建一个宏变量,该变量可以创建一次并反复使用。

    【讨论】:

    • 我知道这一切。我要问的是,使用第一种方法是否有一些我可能不知道的注意事项。
    • 警告是什么意思?在什么意义上?
    • @JasonV - 据我所知,没有任何警告,这是一个偏好和满足要求的问题。
    【解决方案4】:

    这是个人喜好问题。我个人喜欢使用%sysfunc 方法,因为它允许我调试/打印结果,而无需处理任何数据步骤。

    真的,我想说什么可以提高可读性和可维护性。如果您正在与讨厌使用宏的人一起工作,那么请考虑使用更简单的第一种方法。课程用马。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-08
      • 1970-01-01
      相关资源
      最近更新 更多