内宏观引用数组元素做循环 [英] quote array element inside macro do loop

查看:174
本文介绍了内宏观引用数组元素做循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以调用宏 VIO %VIO(道琼斯指数=周五,小时= 8)没有错误。现在,我要嵌套一个DO循环中调用宏。

I can call the macro VIO by %VIO(Dow=Fri,Hour=8) without error. Now I want to nest the call macro inside a do loop.

下面是我试过,但没有运气。

Here's what I have tried but no luck.

%macro trythis;
data _null_;
array ay[3] $3 ('Fri' 'Sat' 'Sun');
%do i = 1 %to dim(ay);
    %do j = 1 %to 24;
        %VIO(ay[&i],&j);
    %end;
%end;   
run;
%mend;

%macro VIO(Dow,Hour);
data Want&Dow.&Hour;
set have(where=(hour="&Hour"));
format dow $3.;
dow = "&Dow";
run;
%mend;

这似乎唉[&放大器; I] 将解析为唉[1] 不是周五

推荐答案

您不能与宏观变量的方式交换数据。宏变量和宏调用之前解决数据步骤甚至编译,更不用说运行。这是很好的,因为它允许宏观变量和宏影响数据汇编一步(即定义哪些列是present,例如)。这也意味着你不能做你想要做的事。尽管它的相似之处,SAS宏语言的的写作功能SAS的方法。您可以编写特定功能风格的宏,但是这不是一回事。

You can't exchange data with macro variables that way. Macro variables and macro calls resolve before the data step is even compiled, not to mention run. This is nice because it allows macro variables and macros to affect the data step compilation (ie, define which columns are present, for example). It also means you can't do what you're trying to do. Despite its similarities, the SAS Macro language is not a method of writing functions in SAS. You can write certain function-style macros, but that's not the same thing.

您不指定宏做什么,所以很难完全回答如何的修复的这一点。

You don't specify what your macro does, so it's difficult to fully answer how to fix this.

如果您的宏需要一个值和宏语言做事情有了它,你需要与数据交互的步骤,您有几种选择:

If your macro takes a value and does things with it in the macro language, and you need to interact with the data step, you have several options:


  1. 重写您的宏钙镁磷肥(SAS的功能书写语言)

  2. 重写您的宏使用宏中的数据的步骤,而不是宏观的语言元素在需要时能够采取数组元素的名称,而不是它的值作为参数

  3. 使用多个数据步骤来完成你的任务

  4. 使用RUN_MACRO和/或DOSUBL(可能结合钙镁磷肥)。这是极有可能的最慢的方法,但它也是最相似的你要怎么做。迪伦埃利斯的 RUN_MACRO运行!详细解释了这种方法。

  1. Rewrite your macro in FCMP (SAS's function-writing language)
  2. Rewrite your macro to use the data step in the macro rather than macro language elements where needed to be able to take the name of the array element rather than its value as an argument
  3. Use multiple data steps to accomplish your task
  4. Use RUN_MACRO and/or DOSUBL (possibly in combination with FCMP). This is very likely the slowest method, but it is also most similar to what you're trying to do. Dylan Ellis' RUN_MACRO Run! explains this method in detail.

如果您不需要与数据交互的一步,这可能是更容易做。


If you don't need to interact with the data step, this may be easier to do.

宏数组是不太一样的数据步数组。他们不是编程语言的实际功能;他们是一个黑客。您可以搜索互联网上对他们的文件;例如,与宏阵列解释一个例子紧循环。

Macro Arrays aren't quite the same as data step arrays. They're not an actual feature of the programming language; they're a hack. You can search for papers on them on the internet; for example, Tight Looping with Macro Arrays explains one example.

总的原则,虽然是非常简单的。您可以使用多个&符号乘决心东西。

The general principle, though, is very straightforward. You use multiple ampersands to multiply resolve something.

%let ay1 = Fri;
%let ay2 = Sat;
%let ay3 = Sun;

%let i=2;

%put &&ay&i.;

如您所愿这将解决。双符号告诉SAS来延迟分辨率一遍,所以&放大器;&安培; AY和放大器;我变成&放大器; AY1 &放大器;我解决但双&放大器;&安培; 只是改变了单个&安培; 被单独留在家中。

This will resolve as you expect. The double ampersand tells SAS to delay resolution one pass, so &&ay&i becomes &ay1 when &i resolves but the double && just changes to a single & and ay is left alone.

所以,你可以做一些容易DO循环:

So you can do something easy with the do loop:

%macro trythis;
  %let ay1=Fri;
  %let ay2=Sat;
  %let ay3=Sun;
  %do i = 1 %to 3;
    %do j = 1 %to 24;
        %VIO(&&ay&i.,&j);
    %end;
  %end;   
%mend;


现在,我想非常清楚地说明:你正在这里一般的方法很可能是一个可怜的,无论是从一个易于编程的角度和观点的速度点。你不给能见度%VIO ,所以很难说你在做什么,或者正确的方法是什么,但是这是很可能不会是正确的。在最低限度,分割所有的部件的成三个或四个宏明确基本上相互依存将导致复杂性保持,并反复运行datastep与单个where子句是非常,非常慢。


Now, I want to state very clearly: the general approach you are taking here is very likely a poor one, both from an easy-to-program point of view and a speed point of view. You don't give visibility to %vio, so it's hard to say what you're doing or what the right approach is, but this is very likely not the right one. At minimum, splitting all of the parts up into three or four macros that clearly substantially interdepend will lead to complexity to maintain, and repeatedly running a datastep with a single where clause is very, very slow.

这篇关于内宏观引用数组元素做循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆