|
On Sun, 13 Jun 2004 12:39:24 -0400, Paul M. Dorfman
<sashole@BELLSOUTH.NET> wrote:
>1. Actually, in Version 9.1, if the input is grouped or indexed, it is not
>necessary to generate any code in order to perform the task, since each
>by-group can be loaded in a hash table one record at a time, and when the
>group is over, it can be dumped into a data set, whose name is a SAS
>expression.
...
hi, Paul,
Actually, in 9.1, data step is not the only one that has access to hash
and iterators. Proc template has them, also. Combined with the put-to-text-
file-and-%include technique, your logic can be implemented in a template
like below.
This is definitely not a practical way to "avoid" macros. But this shows a
way for us to data-driven process from *any* output from procs.
Not being smart enough, of course, I am borrowing shamelessly from Eric
Gebhart's "sql" markup template available at
http://support.sas.com/rnd/base/topics/odsmarkup/sql.html
By the way, I was lucky to hear from Eric several months ago and asked him
a question about the scope of the variables in proc template... his answer
caught me by surprise ... they are all *global* variables.
Well, this is certainly a way to make event-handlers to communicate each
other. And this is more familiar to me mere mortals than xslt's way
(having no "variables," but having to rely on recursive calls to
templates). But I can see the trouble already -- it seems any substantial
template would have to "unset" variables a lot.
Cheers,
Chang
<sasl:code version="9.1.2">
/* proc template to generate a text file with a data step */
/* to be %included. use it with proc print and a var */
/* by chang y. chung on 2004-06-13 */
ods path work.myTmps(update);
proc template;
define style none;
end;
define tagset split;
/* proc print events */
define event colspec_entry;
break /if cmp(name, 'obs');
set $v lowcase(name);
end;
define event table;
start: unset $vs;
finish: trigger split;
end;
define event data;
do /if value;
set $vs[value] strip(value) /if !$vs[value];
done;
end;
define event output;
start:
set $data reverse(label);
set $data scan($data, 1, '.');
set $data reverse($data);
set $data lowcase($data);
end;
/* starts user-defined events */
define event split;
put "data ";
trigger putVs;
putl ";";
putl "set " $data ";";
putl "select (" $v ");";
trigger putWhenV;
putl "end;";
putl "run;";
end;
define event putVs;
iterate $vs;
do /while _value_;
put _value_ " ";
next $vs;
done;
end;
define event putWhenV;
iterate $vs;
do /while _value_;
putl "when('" _value_ "') output " _value_ ";";
next $vs;
done;
end;
end; /* of define tagset split */
run;
data one;
do v ='a', 'a', 'b', 'c';
output;
end;
run;
ods listing close;
ods markup type=split file="c:\split.sas" style=none;
proc print data=one;
var v;
run;
ods markup close;
ods path reset;
%include "c:\split.sas" /source2;
/* on log
83 %include "c:\split.sas" /source2;
NOTE: %INCLUDE (level 1) file c:\split.sas is file c:\split.sas.
84 +data a b c ;
85 +set one;
86 +select (v);
87 +when('a') output a;
88 +when('b') output b;
89 +when('c') output c;
90 +end;
91 +run;
NOTE: There were 4 observations read from the data set WORK.ONE.
NOTE: The data set WORK.A has 2 observations and 1 variables.
NOTE: The data set WORK.B has 1 observations and 1 variables.
NOTE: The data set WORK.C has 1 observations and 1 variables.
*/
</sasl:code>
|