v8.2 macro question - passing the contents of a data step var iabl e to a macro

v8.2 macro question - passing the contents of a data step var iabl e to a macro

Post by Diskin, Denn » Fri, 03 Aug 2001 01:35:15



Harry,

I don't think you quite have the concept of macros. The macro is processed
at COMPILE time. At execution time, the code has all been generated.
The example you used could easily be done with no macros at all.

If you'd give an example of what you're trying to accomplish.

hth,
Dennis Diskin

> -----Original Message-----

> Sent: Wednesday, August 01, 2001 12:27 PM

> Subject:      v8.2 macro question - passing the contents of a data step
> variabl e to a macro

> Listers:

> In v8.2, is it possible to invoke a macro within a data step and pass to
> the
> macro the contents of a data step variable defined within that datastep?
> Note that the following silliness is for illustration only, the real macro
> has some meat that requires it to be a macro.

> e.g.
> %global other;
> %macro dumb_macro(stuff);
>     %let other = %scan(&stuff,1,'/');
> %mend;

> data harry;
>    input 'c:\test.txt';
>    input var1 var2 var3;
>    %dumb_macro(var1);  /* passes the literial 'var1' rather than contents
> of
> var1 */
>    var4 = "&other";
> run;

> Adding call symput( ) doesn't help since the symput'ed variable isn't
> available until the data step completes.

> Am I destined to do something like the following:

> data harry;
>    retain x 0;
>    infile 'c:\blah.txt' end=eof;
>    input var1 var2 var3;
>    call symput('var'||trim(left(x)),var1);
>    if eof then call symput('limit',x);
> run;

> %macro loop;
> %local x;
> data second;
>  %do x = 1 %to &limit;
>      %dumb_macro(&&var&x);
>       var4 = "&other";
>       output;
>    %end;
> run;
> %mend loop;
> %loop;

> then merge datasets 'harry' and 'second'.

> TIA

 
 
 

v8.2 macro question - passing the contents of a data step var iabl e to a macro

Post by Droogendyk, Har » Fri, 03 Aug 2001 02:25:34


Dennis et al:

Yes, my understanding of macros can be improved!  I think I do understand
that the macro is processed at compile time, I'm hoping against hope there's
a means of tying data step variables to macro, thus allowing data step
variables to be used as parms to a macro.

As I said, %dumb_macro was only for illustration purposes, that function
could obviously be done without incorporating macro processing at all.

The real task?  I'm processing Apache web server logs, and attempting to
create SAS dataset variables for each name/value pair I find in the
parameter portion of SAS/Intrnet urls, where the SAS dataset variable will
be set to the value specified in the URL.  It's almost like a reverse CALL
VNAME.

e.g.  _program=library.program.sas&var1=george&var2=tom&var3=sam

The real macro is:

%macro rip(str);
    %local i limit pair;
    %let limit = %eval(%length(&str) - %length(%sysfunc(compress(&str,'&')))
+ 1);
    %do i = 1 %to &limit;
        %let pair  = %scan(&str,%eval(&i),'&');
        %scan(&pair,1,'=') = "%scan(&pair,2,'=')";
    %end;
%mend rip;

where usage like the following works splendidly:

%let url =
%nrstr(_program=library.program.sas&var1=george&var2=tom&var3=sam);
data stuff;
    %rip(&url);
run;

The SAS System        09:29 Wednesday, August 1, 2001   2

Obs         _program           var1     var2    var3

 1     library.program.sas    george    tom     sam

I'd like to incorporate %rip in the original data step that reads the Apache
log file and creates another 15 variables.  Based on my understanding of
macro, it appears that two data steps and a merge are required; I was trying
to get away with one data step.

-----Original Message-----

Sent:   August 1, 2001 12:35 PM

Subject:        Re: v8.2 macro question - passing the contents of a data

step var iabl e to a macro

Harry,

I don't think you quite have the concept of macros. The macro is processed
at COMPILE time. At execution time, the code has all been generated.
The example you used could easily be done with no macros at all.

If you'd give an example of what you're trying to accomplish.

hth,
Dennis Diskin

> -----Original Message-----

> Sent: Wednesday, August 01, 2001 12:27 PM

> Subject:      v8.2 macro question - passing the contents of a data step
> variabl e to a macro

> Listers:

> In v8.2, is it possible to invoke a macro within a data step and pass to
> the
> macro the contents of a data step variable defined within that datastep?
> Note that the following silliness is for illustration only, the real macro
> has some meat that requires it to be a macro.

> e.g.
> %global other;
> %macro dumb_macro(stuff);
>     %let other = %scan(&stuff,1,'/');
> %mend;

> data harry;
>    input 'c:\test.txt';
>    input var1 var2 var3;
>    %dumb_macro(var1);  /* passes the literial 'var1' rather than contents
> of
> var1 */
>    var4 = "&other";
> run;

> Adding call symput( ) doesn't help since the symput'ed variable isn't
> available until the data step completes.

> Am I destined to do something like the following:

> data harry;
>    retain x 0;
>    infile 'c:\blah.txt' end=eof;
>    input var1 var2 var3;
>    call symput('var'||trim(left(x)),var1);
>    if eof then call symput('limit',x);
> run;

> %macro loop;
> %local x;
> data second;
>  %do x = 1 %to &limit;
>      %dumb_macro(&&var&x);
>       var4 = "&other";
>       output;
>    %end;
> run;
> %mend loop;
> %loop;

> then merge datasets 'harry' and 'second'.

> TIA


 
 
 

v8.2 macro question - passing the contents of a data step var iabl e to a macro

Post by Terjeson, Ma » Fri, 03 Aug 2001 02:48:51


Hi Harry,

One of the easiest ways to troubleshoot macros
is to first say to yourself "macros is nothing
more than text substitution".  For expert or
beginner, saying "macro stuff is purely text
substitution", will answer nearly all but the
extraordinary.  Whatever the result of the macro
is will get placed in the datastep at that point.

One additional rule you have to memorize is that
macro variables generated within a datastep are
not available until AFTER the datastep is over.
(I know there are some technical variances folks
will point out here, but in the general/practical
sense, plan on them not being available until after)

However, all is not lost.  Depending on the task
that you are doing.  1) are you wanting to make
adjustments *during* your datastep, or 2) have
a value available *after* your datastep.  Because
of the first two paragraphs above as rules, you
have to determine these two questions, *during*
or *after*.

Okay, for the *during* -----------
Unlike other programming languages that have what
they call "macros", they are more or less a real
*callable subroutine*.  In SAS, the "macros"
actually have a greater flexibility by being complex
"text substitution".  Picture that your code is
first sent through the macro parser that will
substitute the passed and derived *text* replacements
and then substitute in into your datastep code,
...and THEN, it goes through the datastep parser
as if you had manually hard coded everything. So
picturing text substitution as we go along below.

So if you wanted to perform some adjustments on one
of your datastep variables with a scan() function
you can use the text substitution viewpoint and
write your macro like this:

    * create sample data ;
data _null_;
   file 'c:\temp\test.txt';
   put '111 222 333';
run;

%macro dumb_macro(stuff);
    var4 = scan(&stuff,1,'/');
%mend;

data harry;
   infile 'c:\temp\test.txt';
   input var1 var2 var3;
   %dumb_macro(var1);
   put _all_;
run;

-----which in text substitution terms means that
when it gets to the datastep parser the replaced
code looks like this:

data harry;
   infile 'c:\temp\test.txt';
   input var1 var2 var3;
   var4 = scan(var1,1,'/');
   put _all_;
run;

-----and thus, what you see above truely is what
results you will get.

As for having your values available *after* the
datastep.

data harry;
   infile 'c:\temp\test.txt';
   input var1 var2 var3;
   call symput("MYVAR",var1);
   put _all_;
run;

%put Now available after is MYVAR as >&myvar<;

* You will notice leading spaces in the result ;
* from CALL SYMPUT().  You can easily get rid  ;
* of these my another re-assignment with %LET. ;

%let myvar=&myvar;
%put Now available after is MYVAR as >&myvar<;

* Also, the MYVAR is still available for more ;
* datasteps to follow such as:                ;

data _null_;
    sss = "&myvar";
    put 'MYVAR is still available here. myvar=' sss;
run;

I know SAS macros have evolved into something much more
sophisticated and intricate, but the "text substitution"
viewpoint has helped many-a-folk, novice and expert to
walk through in their mind what is happening.  SAS macros
indeed are great for eliminating repetitive code and other
handy methods of modularizing tasks.

Hope this is helpful,
Mark Terjeson
Washington State Department of Social and Health Services
Division of Research and Data Analysis (RDA)

-----Original Message-----

Sent: Wednesday, August 01, 2001 9:27 AM

Subject: v8.2 macro question - passing the contents of a data step

variabl e to a macro

Listers:

In v8.2, is it possible to invoke a macro within a data step and pass to the
macro the contents of a data step variable defined within that datastep?
Note that the following silliness is for illustration only, the real macro
has some meat that requires it to be a macro.

e.g.
%global other;
%macro dumb_macro(stuff);
    %let other = %scan(&stuff,1,'/');
%mend;

data harry;
   input 'c:\test.txt';
   input var1 var2 var3;
   %dumb_macro(var1);  /* passes the literial 'var1' rather than contents of
var1 */
   var4 = "&other";
run;

Adding call symput( ) doesn't help since the symput'ed variable isn't
available until the data step completes.

Am I destined to do something like the following:

data harry;
   retain x 0;
   infile 'c:\blah.txt' end=eof;
   input var1 var2 var3;
   call symput('var'||trim(left(x)),var1);
   if eof then call symput('limit',x);
run;

%macro loop;
%local x;
data second;
 %do x = 1 %to &limit;
     %dumb_macro(&&var&x);
      var4 = "&other";
      output;
   %end;
run;
%mend loop;
%loop;

then merge datasets 'harry' and 'second'.

TIA

 
 
 

v8.2 macro question - passing the contents of a data step var iabl e to a macro

Post by Diskin, Denn » Fri, 03 Aug 2001 03:31:56


Harry,

Here's what I see as the problem: SAS has to be able to build a table at the
start of the data step which contains all of the variables. (the PDV or
Program Data Vector).
It can not handle adding variables based on the input data. SAS must also
know the maximum lengths of string variables at this point.

How many possibilities are there for different names ?  How many records do
you expect at each execution /

There are several approaches which might solve this.

1. If there are a limited number of names possible, it could be handled in
datastep code by having all the possible names present.
2. The left hand side name (e.g. _program) could be stored in a variable
(say VNAME) and it's value in another variable (say VVALUE).
3. The input stream could be read by a macro (using %SYSFUNC calls) and then
the macro variables can be used to construct the datastep. This can be very
messy.

Your idea of creating two data sets and merging confuses me. I don't see how
this would help but, maybe I just don't follow what's being attempted.

hth,
Dennis Diskin

> -----Original Message-----

> Sent: Wednesday, August 01, 2001 1:26 PM

> Subject:      Re: v8.2 macro question - passing the contents of a data
> step var iabl e to a macro

> Dennis et al:

> Yes, my understanding of macros can be improved!  I think I do understand
> that the macro is processed at compile time, I'm hoping against hope
> there's
> a means of tying data step variables to macro, thus allowing data step
> variables to be used as parms to a macro.

> As I said, %dumb_macro was only for illustration purposes, that function
> could obviously be done without incorporating macro processing at all.

> The real task?  I'm processing Apache web server logs, and attempting to
> create SAS dataset variables for each name/value pair I find in the
> parameter portion of SAS/Intrnet urls, where the SAS dataset variable will
> be set to the value specified in the URL.  It's almost like a reverse CALL
> VNAME.

> e.g.  _program=library.program.sas&var1=george&var2=tom&var3=sam

> The real macro is:

> %macro rip(str);
>     %local i limit pair;
>     %let limit = %eval(%length(&str) -
> %length(%sysfunc(compress(&str,'&')))
> + 1);
>     %do i = 1 %to &limit;
>         %let pair  = %scan(&str,%eval(&i),'&');
>         %scan(&pair,1,'=') = "%scan(&pair,2,'=')";
>     %end;
> %mend rip;

> where usage like the following works splendidly:

> %let url =
> %nrstr(_program=library.program.sas&var1=george&var2=tom&var3=sam);
> data stuff;
>     %rip(&url);
> run;

> The SAS System        09:29 Wednesday, August 1, 2001   2

> Obs         _program           var1     var2    var3

>  1     library.program.sas    george    tom     sam

> I'd like to incorporate %rip in the original data step that reads the
> Apache
> log file and creates another 15 variables.  Based on my understanding of
> macro, it appears that two data steps and a merge are required; I was
> trying
> to get away with one data step.

> -----Original Message-----

> Sent:   August 1, 2001 12:35 PM

> Subject:        Re: v8.2 macro question - passing the contents of a data
> step var iabl e to a macro

> Harry,

> I don't think you quite have the concept of macros. The macro is processed
> at COMPILE time. At execution time, the code has all been generated.
> The example you used could easily be done with no macros at all.

> If you'd give an example of what you're trying to accomplish.

> hth,
> Dennis Diskin

> > -----Original Message-----

> > Sent: Wednesday, August 01, 2001 12:27 PM

> > Subject:      v8.2 macro question - passing the contents of a data step
> > variabl e to a macro

> > Listers:

> > In v8.2, is it possible to invoke a macro within a data step and pass to
> > the
> > macro the contents of a data step variable defined within that datastep?
> > Note that the following silliness is for illustration only, the real
> macro
> > has some meat that requires it to be a macro.

> > e.g.
> > %global other;
> > %macro dumb_macro(stuff);
> >     %let other = %scan(&stuff,1,'/');
> > %mend;

> > data harry;
> >    input 'c:\test.txt';
> >    input var1 var2 var3;
> >    %dumb_macro(var1);  /* passes the literial 'var1' rather than
> contents
> > of
> > var1 */
> >    var4 = "&other";
> > run;

> > Adding call symput( ) doesn't help since the symput'ed variable isn't
> > available until the data step completes.

> > Am I destined to do something like the following:

> > data harry;
> >    retain x 0;
> >    infile 'c:\blah.txt' end=eof;
> >    input var1 var2 var3;
> >    call symput('var'||trim(left(x)),var1);
> >    if eof then call symput('limit',x);
> > run;

> > %macro loop;
> > %local x;
> > data second;
> >  %do x = 1 %to &limit;
> >      %dumb_macro(&&var&x);
> >       var4 = "&other";
> >       output;
> >    %end;
> > run;
> > %mend loop;
> > %loop;

> > then merge datasets 'harry' and 'second'.

> > TIA

 
 
 

1. v8.2 macro question - passing the contents of a data step var iable to a macro

Andreas:

No, no, I was the one with the half-baked solution.  I was merely pointing
out that I was attempting to solve a problem one way ( half-baked because it
didn't work, mixing macro and data step ) and Puddin' Man suggested an
entirely new solution that did work.

Please understand that I'm appreciative of each suggestion / solution
provided; each one is an opportunity to broaden my knowledge of SAS.

Regards,
Harry

2. Paperport and USB drivers

3. v8.2 macro question - passing the contents of a data step variabl e to a macro

4. Marble Madness

5. v8.2 macro question - passing the contents of a data step

6. Missing Charts in Monthly Reports

7. How to assign a data step character value to a macro var

8. Please Post New Toshiba 6X Driver (spin-down fix)

9. Thanks - v8.2 macro question - passing the contents of a data ste p variabl e to a macro

10. macro help: reference %global macro vars

11. A question about macro invocation within data step

12. SYSPARM: MACRO v Data Step question

13. MSExcel button macro pass var how?