简体   繁体   中英

SAS Do Over Macro - Backwards

I am using the Macro Arrays and Do Over Macro .

I would like to rewrite this code with a do over macro:

if mysequence > 4 then grammar_last_5 = grammar_last_4;
if mysequence > 3 then grammar_last_4 = grammar_last_3;
if mysequence > 2 then grammar_last_3 = grammar_last_2;
if mysequence > 1 then grammar_last_2 = grammar_last_1;

So my Do Over would look something like:

%do_over(values=2-5, phrase= if mysequence > %eval(6-?) then grammar_last_%eval(7-?) = grammar_last_%eval(6-?);)

But that doesn't work.

Does anyone know how this can be done?

Thanks!! Adam

For others wondering, the macros appear to be available here: http://www.sascommunity.org/wiki/Tight_Looping_with_Macro_Arrays

You've got a problem though. You're trying to pass in %eval(6-?) and other functions like text to the %do_over macro. Its going to try to compute that function and pass the result to the macro, and because its finding a character in what should be a mathematical operation, I'm guessing it subsequently is throwing a bit of a tantrum.

What's more, a way to do what you want doesn't seem like it would be forthcoming, because you'd need to mask the function from the macro compiler as you're feeding it in as an argument, but then unmask it to the macro compiler as its actually being used by do_over, and I'm guessing do_over isn't going to understand what you want without rewriting its logic even if you succeeded.

May I humbly suggest your own macro code as a starting solution. Something like:

%do i = 5 %to 2 %by -1;

if mysequence > %eval(&i - 1) then grammar_last_&i = grammar_last_%eval(&i - 1);
%end;

This should produce the text you want, though you would need to put it in your own macro, and call it in a data step, as it wouldn't make much sense anywhere else.

If you're going to want something more generalized, you're going to have to get your hands much much messier...

I took a quick look at the macro and it looks like they use macro quoting functions which could be interfering with the execution of your %eval functions.

If this is the case then you would have to custom edit %do_over() so that it didn't do this. If so then it's probably not worth the effort. It would be easier to write your own one-off macro to achieve your goal.

You don't need a macro for that, unless you've got something you're not telling us.

if mysequence > 4 then grammar_last_5 = grammar_last_4;
if mysequence > 3 then grammar_last_4 = grammar_last_3;
if mysequence > 2 then grammar_last_3 = grammar_last_2;
if mysequence > 1 then grammar_last_2 = grammar_last_1;

->

array  grammars grammar_last:;
do _t = 4 to 1 by -1; *or, _t = dim(grammars)-1 to 1 by -1;
 if mysequence > _t then grammars[_t+1]=grammars[_t];
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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