|
I'm enjoying this thread, having run into something similar.
I was trying to develop a macro that would calculate a new variable from
a pair of existing variables, which is easy to do, but not knowing
whether the existing variables are numeric or character. So I was also
trying to pull the existing variable's attributes (type, length, format,
label) to apply to the new variable. And all this macro code would be
done within a data step, not across data steps. Well, of course, one
can't use Call Symput to put the type via VTYPE() into a macro variable
and then use that same macro variable in the section of the macro within
the data step, as we've seen - the macro symbol tables aren't filled
until after the step boundary. I ended up pulling the attribute bit and
just applying length and format etc around the macro call (length
statement before the call, and format statement after). The variable
type became a parameter.
Still, it would be nice to be able to apply one variable's attribute to
another via some sort of function or method.
To apply this to this thread, if there was a way to call Proc SQL to
create a macro variable holding the value of VTYPE(), and have it
available during the data step compilation, would be nice. Or something
similar...
John Gerstle
Scientific Information Specialist
Centers for Disease Control and Prevention
NCHHSTP\DHAP-SE\QSDMB\Data Management Team
Phone: 404-639-3980
Fax: 404-639-8642
Email: yzg9 at cdc dot gov
Socrates, proclaimed: "I came to know one thing; that I know nothing".
>>-----Original Message-----
>>From: owner-sas-l@listserv.uga.edu
[mailto:owner-sas-l@listserv.uga.edu] On
>>Behalf Of Joe Whitehurst
>>Sent: Thursday, August 13, 2009 11:23 AM
>>To: Randy Herbison
>>Cc: Gerhard Hellriegel; SAS-L@LISTSERV.UGA.EDU
>>Subject: Re: Can I use proc in data step? (Here's an example of 38
Procs Being
>>Submitted _AND_ Executed While the SUBMITing Data Step Is Still
Executing)
>>
>>Randy,
>>In this experiment, I kept the data step view as simple as possible by
using
>>only data step DATA and SET statements, and they worked as I
expected--the
>>entire CLASS dataset was read which is not directly referenced
anywhere in
>>the SAS Component Language program. But, your point begs for another
>>experiment in which I have macro variable values that are passed from
a
>>SUBMITed PROC or DATA STEP returned to the executing data step and
>>interacting with some original data step statements--as I write that
>>sentence now I'm becoming skeptical too. So I'll add some more data
step
>>statements to the initial view and conduct another experiment. I'm
always
>>up for learning something new, refining what I already know or
correcting
>>something I thought I knew but didn't. I first used this technique in
a
>>rather complex web log parsing data step in which I was more concerned
with
>>writing to memory (SCL Lists not Macro Variables) than reading from
memory.
>> I think the challenge will be to get a data step to compile without
>>something it will use later during execution. I may have to resort to
>>trickery, sorcery or even memory pokes.
>>
>>Joe
>>
>>On Thu, Aug 13, 2009 at 10:50 AM, Randy Herbison
>><RandyHerbison@westat.com>wrote:
>>
>>> Joe,
>>>
>>>
>>>
>>> I don't think it is correct to say that you passed the macro
variable
>>> values back to the executing data step, but I suspect that we
disagree about
>>> what constitutes the data step. I think of it as the execution of
the
>>> original data step statements. You seem to think of it as the
entire
>>> context, including SCL, in which the view is used.
>>>
>>>
>>>
>>> My data step view included an assignment based on the value of a
macro
>>> variable:
>>>
>>>
>>>
>>> data class_v / view=class_v;
>>> set sashelp.class;
>>> x=_n_;
>>> if symexist('_xname') then xname=symget('_xname');
>>> run;
>>>
>>> What I attempted to show is that the PROC SQL generated macro
variable
>>> values, generated between fetches from the view, would not be
available to
>>> the data step statement:
>>>
>>>
>>>
>>> if symexist('_xname') then xname=symget('_xname');
>>>
>>> Your code reads from a view. I think we both see that as
involving data
>>> step processing. Your code then uses SCL to do the update
processing for a
>>> new data set. I don't see that as data step processing.
>>>
>>>
>>>
>>> -Randy
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> *From:* Joe Whitehurst [mailto:joewhitehurst@gmail.com]
>>> *Sent:* Thursday, August 13, 2009 2:22 AM
>>> *To:* Randy Herbison
>>> *Cc:* Gerhard Hellriegel; SAS-L@LISTSERV.UGA.EDU
>>> *Subject:* Re: Can I use proc in data step? (Here's an example of 38
Procs
>>> Being Submitted _AND_ Executed While the SUBMITing Data Step Is
Still
>>> Executing)
>>>
>>>
>>>
>>> Randy,
>>>
>>>
>>>
>>> I conducted my experiment and got the results I expected. I created
a
>>> simple data step view with the SASHELP.CLASS dataset. I opened it
in a SAS
>>> Component Language programs and read it in a loop. For each
observation
>>> coming in, I conditionally ran a PROC MEANS to calculate the
person's ill
>>> gotten gains and a data step to assign a party affiliation. I
passed both
>>> results back to the executing data step via macro variables and both
results
>>> showed up on the output dataset from the data step. The entire data
step
>>> submitted 38 PROCs (19 PROC MEANSs and 19 PROC DELETEs and 19 data
>>steps)
>>> all of which executed and passed their results back to the
submitting data
>>> step while it was executing (before any step boundaries).
>>>
>>>
>>>
>>> 1. Here is the simple data step view:
>>>
>>>
>>>
>>> data
>>>
>>sasuser.bad_ass_proc_submitting_datastep/view=sasuser.bad_ass_proc_sub
mitti
>>ng_datastep;
>>>
>>> set sashelp.class;
>>>
>>> run;
>>>
>>>
>>>
>>> 2. Here is the SAS Component language Program that used the data
step view
>>> to submit PROCs:
>>>
>>>
>>>
>>> length name $8 sex $1 party_affiliation $30;
>>>
>>>
>>> init:
>>>
>>>
>>> age=.;
>>>
>>>
>>> height=.;
>>>
>>>
>>> weight=.;
>>>
>>>
>>> ill_gotten_gains=.;
>>>
>>>
>>> class_dsid=open('sasuser.bad_ass_proc_submitting_datastep','i');
>>>
>>>
>>> call set(class_dsid);
>>>
>>>
>>> ill_gotten_gains_dsid=open('ill_gotten_gains','n');
>>>
>>>
>>> rc=newvar(ill_gotten_gains_dsid,'age','n',8);
>>>
>>>
>>> rc=newvar(ill_gotten_gains_dsid,'height','n',8);
>>>
>>>
>>> rc=newvar(ill_gotten_gains_dsid,'weight','n',8);
>>>
>>>
>>> rc=newvar(ill_gotten_gains_dsid,'ill_gotten_gains','n',8);
>>>
>>>
>>> rc=newvar(ill_gotten_gains_dsid,'name','c',8);
>>>
>>>
>>> rc=newvar(ill_gotten_gains_dsid,'party_affiliation','c',30);
>>>
>>>
>>> closerc=close(ill_gotten_gains_dsid);
>>>
>>>
>>> ill_gotten_gains_dsid=open('ill_gotten_gains','U');
>>>
>>>
>>> call set(ill_gotten_gains_dsid);
>>>
>>>
>>> do while(fetch(class_dsid)=0);
>>>
>>>
>>> put 'working' name=;
>>>
>>>
>>> if sex='M' then do;
>>>
>>>
>>> link ill_gotten_gains1;
>>>
>>>
>>> rc=append(ill_gotten_gains_dsid);
>>>
>>>
>>> end;
>>>
>>>
>>> else if sex='F' then do;
>>>
>>>
>>> link ill_gotten_gains2;
>>>
>>>
>>> rc=append(ill_gotten_gains_dsid);
>>>
>>>
>>> end;
>>>
>>>
>>> end;
>>>
>>>
>>>
>>>
>>>
>>> closerc1=close(class_dsid);
>>>
>>>
>>> closerc2=close(ill_gotten_gains_dsid);
>>>
>>>
>>> submit continue;
>>>
>>>
>>> proc sort data=ill_gotten_gains;
>>>
>>>
>>> by party_affiliation;
>>>
>>>
>>> Title "Class Dataset With Ill Gotten Gains By Party
affiliation";
>>>
>>>
>>> proc print data=ill_gotten_gains;
>>>
>>>
>>> var name ill_gotten_gains;
>>>
>>>
>>> by party_affiliation;
>>>
>>>
>>> sumby party_affiliation;
>>>
>>>
>>> format ill_gotten_gains dollar12.;
>>>
>>>
>>> run;
>>>
>>>
>>>
>>>
>>>
>>> endsubmit;
>>>
>>>
>>> return;
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> ill_gotten_gains1:
>>>
>>>
>>> submit continue;
>>>
>>>
>>> proc means data=sashelp.prdsale noprint;
>>>
>>>
>>> var actual;
>>>
>>>
>>> output out=ill_gotten_gains_sum sum=ill_gotten_gains;
>>>
>>>
>>> run;
>>>
>>>
>>> data _null_;
>>>
>>>
>>> set ill_gotten_gains_sum;
>>>
>>>
>>> call symput('ill_gotten_gains',left(ill_gotten_gains));
>>>
>>>
>>> call symput('party_affiliation','Disgusting Rebugnican');
>>>
>>>
>>> run;
>>>
>>>
>>> proc delete data=ill_gotten_gains_sum;run;
>>>
>>>
>>> %put Party_Affiliation=&party_affiliation
>>> ill_gotten_gains=&ill_gotten_gains;
>>>
>>>
>>> endsubmit;
>>>
>>>
>>> ill_gotten_gains=input(symget('ill_gotten_gains'),dollar15.);
>>>
>>>
>>> party_affiliation=symget('party_affiliation');
>>>
>>>
>>> return;
>>>
>>>
>>>
>>>
>>>
>>> ill_gotten_gains2:
>>>
>>>
>>> submit continue;
>>>
>>>
>>> proc means data=sashelp.prdsale noprint;
>>>
>>>
>>> var actual;
>>>
>>>
>>> output out=ill_gotten_gains_sum sum=ill_gotten_gains;
>>>
>>>
>>> run;
>>>
>>>
>>> data _null_;
>>>
>>>
>>> set ill_gotten_gains_sum;
>>>
>>>
>>> ill_gotten_gains=ill_gotten_gains/100000;
>>>
>>>
>>> call symput('ill_gotten_gains',left(ill_gotten_gains));
>>>
>>>
>>> call symput('party_affiliation','Sensible Democrat');
>>>
>>>
>>> run;
>>>
>>>
>>> proc delete data=ill_gotten_gains_sum;run;
>>>
>>>
>>> %put Party_Affiliation=&party_affiliation
>>> ill_gotten_gains=&ill_gotten_gains;
>>>
>>>
>>> endsubmit;
>>>
>>>
>>> ill_gotten_gains=input(symget('ill_gotten_gains'),dollar15.);
>>>
>>>
>>> party_affiliation=symget('party_affiliation');
>>>
>>>
>>> return;
>>>
>>>
>>>
>>> 3. Here is the output:
>>>
>>>
>>>
>>> Class Dataset With Ill Gotten Gains By Party
>>> affiliation 4
>>>
>>>
00:02
>>> Thursday, August 13, 2009
>>>
>>>
>>>
>>> ---------------------------- party_affiliation=Disgusting Rebugnican
>>> -----------------------------
>>>
>>>
>>>
>>>
ill_gotten_
>>>
>>> Obs name
gains
>>>
>>>
>>>
>>> 1 Alfred
$730,337
>>>
>>> 2 Henry
$730,337
>>>
>>> 3 James
$730,337
>>>
>>> 4 Jeffrey
$730,337
>>>
>>> 5 John
$730,337
>>>
>>> 6 Philip
$730,337
>>>
>>> 7 Robert
$730,337
>>>
>>> 8 Ronald
$730,337
>>>
>>> 9 Thomas
$730,337
>>>
>>> 10 William
$730,337
>>>
>>> -----------------
------------
>>>
>>> party_affiliation
$7,303,370
>>>
>>>
>>>
>>>
>>>
>>> ------------------------------ party_affiliation=Sensible Democrat
>>> -------------------------------
>>>
>>>
>>>
>>>
ill_gotten_
>>>
>>> Obs name
gains
>>>
>>>
>>>
>>> 11 Alice
$7
>>>
>>> 12 Barbara
$7
>>>
>>> 13 Carol
$7
>>>
>>> 14 Jane
$7
>>>
>>> 15 Janet
$7
>>>
>>> 16 Joyce
$7
>>>
>>> 17 Judy
$7
>>>
>>> 18 Louise
$7
>>>
>>> 19 Mary
$7
>>>
>>> -----------------
------------
>>>
>>> party_affiliation
$66
>>>
>>>
============
>>>
>>>
$7,303,436
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Wed, Aug 12, 2009 at 2:38 PM, Randy Herbison
>><RandyHerbison@westat.com>
>>> wrote:
>>>
>>> Joe wrote:
>>>
>>> "I believe you can. You can execute one or many PROCs right inside
a
>>> _PROPERLY_ constructed and _PROPERLY_ executed data step. Here's
how:
>>> 1. create the data step you want and make it a view.
>>>
>>> 2. Open the view in a SAS Component Language program.
>>>
>>> 3. Read it is a loop.
>>>
>>> 4. Based on data step variable values, conditionally execute as many
SUBMIT
>>> blocks as you wish and put as many PROCs as you wish in each one.
>>>
>>> 5. Use macro variables to get PROC output data back to your
executing data
>>> step.
>>>
>>> It's just that simple."
>>>
>>> The code below shows that it is possible to run a PROC step while
using a
>>> data step view. While reading from the view, the PROC SQL step
executes for
>>> each value of X.
>>>
>>> I'm skeptical about #5. I don't think the updated macro variable
value is
>>> available to the view until the view is opened again after the PROC
SQL
>>> steps have run.
>>>
>>> -Randy
>>>
>>>
>>> data class;
>>> set sashelp.class;
>>>
>>> x=_n_;
>>> run;
>>>
>>> %symdel _xname;
>>> data class_v / view=class_v;
>>> set sashelp.class;
>>> x=_n_;
>>> if symexist('_xname') then xname=symget('_xname');
>>> put 'XXXXXXXXXXXXXXXXXX';
>>> run;
>>>
>>> *** SCL ***;
>>> dcl char(12) xname _xname;
>>>
>>> init:
>>> dsid=open('class_v');
>>> if dsid then do;
>>> do while (fetch(dsid)=0);
>>> x=getvarn(dsid,varnum(dsid,'x'));
>>> submit continue;
>>> proc sql;
>>> select 'X' || name into :_xname from class
>>> where x=&x;
>>> quit;
>>> endsubmit;
>>> xname=getvarc(dsid,varnum(dsid,'xname'));
>>> _xname=symget('_xname');
>>> put xname= _xname=;
>>> end;
>>> dsid=close(dsid);
>>> end;
>>> submit;
>>> %symdel _xname;
>>> endsubmit;
>>> return;
>>>
>>>
>>>
>>>
>>> -----Original Message-----
>>> From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of
>>> Gerhard Hellriegel
>>> Sent: Wednesday, August 12, 2009 1:19 PM
>>> To: SAS-L@LISTSERV.UGA.EDU
>>> Subject: Re: Can I use proc in data step?
>>>
>>> it is not only not possible to use a PROC in the middle of a
DATA-step, it
>>> also makes no sense!
>>> In a data-step a automatic loop over all records of a dataset (if
there is
>>> a SET) is built and each statement is executed for each record.
Imagine a
>>> PROC PRINT DATA=SASHELP.CLASS...; is that statement (the purpose is
to
>>> print a list of all records of CLASS), should that PROC run for each
>>> iteration of the dataset in SET? Perhaps 5 mio? So 5 mio lists of
>>> SASHELP.CLASS???
>>>
>>> That is simply nonsense!
>>>
>>> A macro or call execute or a file-put to write a include-file will
NOT
>>> change that behaviour! Also not Joe's SCL - SUBMIT blocks! A
DATA-step is
>>> NOT designed for that and all the generated statements are executed
AFTER
>>> the DATA-step ends! Yes, you can dynamicly generate steps (PROCs and
>>DATA)
>>> with macros or other ways, but if you create NESTED steps, you'll
get a
>>> error!
>>>
>>> That what all that discussion might point to, are user-written
functions,
>>> not PROCs. If someone don't find a function to do what he wants
(hard to
>>> believe), it might be a way, which seems also to be better supported
in
>>> future SAS releases (?).
>>>
>>> Gerhard
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Wed, 12 Aug 2009 11:50:31 -0500, Matthew Pettis
>>> <matt.pettis@THOMSONREUTERS.COM> wrote:
>>>
>>> >On the other hand, you may have a dataset that you want to use as a
>>> >controlling dataset to execute a repetitive set of calls to a
sequence
>>> >of procs and datasteps. I highly recommend the macro presented
here:
>>>
>>>http://www.wuss.org/proceedings08/08WUSS%20Proceedings/papers/app/app
04
>>.
>>> >pdf
>>> >
>>> >(I did a far inferior implementation of this for my purposes, and
even
>>> >presented on it, but have since thrown it away and used this).
>>> >
>>> >The key is to understand why you want to call other procs from the
>>> >middle of your datastep. If you think you need a proc to compute
the
>>> >mean of a row of values, then, like the people here are saying,
there is
>>> >a better way to do it. However, the case in which I use this macro
is
>>> >different. In my case, I want to collect data from a series of
HTTP
>>> >locations, which I have in a dataset, and make one large dataset of
the
>>> >contents of the URL from the different locations. So, I need to
create
>>> >a new 'filename' statement for each different URL, slurp the
contents
>>> >into a dataset, and append it to a master. That is where I use the
>>> >'%for' macro detailed here -- to execute repeatedly a set of open
SAS
>>> >statements with a different value for the different 'filename' URL
>>> >locations.
>>> >
>>> >So, in conclusion, yes, you can call procs (and other open code
>>> >statements) from within a data step, but you really need to know
whether
>>> >what you are doing is necessary or is better handled in an
alternative
>>> >manner.
>>> >
>>> >Perhaps if you would post the particular problem you want to solve
with
>>> >the 'proc' calls from a datastep, you may (read: will likely) get
some
>>> >good feedback on how to solve the problem.
>>> >
>>> >HTH,
>>> >Matt
>>> >
>>> >
>>> >-----Original Message-----
>>> >From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf
Of
>>> >Chris Brooks
>>> >Sent: Wednesday, August 12, 2009 10:01 AM
>>> >To: SAS-L@LISTSERV.UGA.EDU
>>> >Subject: Re: Can I use proc in data step?
>>> >
>>> >Tim
>>> >
>>> >It is theoretically possible with call execute eg
>>> >
>>> >data class;
>>> > set sashelp.class;
>>> > if _n_=1 then call execute('proc means data=sashelp.class;var
>>> >height;output out=tempout;run;');
>>> >
>>> >run;
>>> >
>>> >To be honest though I think it's a bad idea and you could be
opening
>>> >yourself up to a whole world of pain if you try to use the output
from
>>> >the
>>> >proc within the same step. As others have suggested it's almost
>>> >certainly
>>> >better to try to find another way.
>>> >
>>> >Chris Brooks
>>> >SAS Technical Lead
>>> >Office for National Statistics
>>> >United Kingdom
>>> >
>>> >On Wed, 12 Aug 2009 10:22:16 -0400, Tim, Choi <yschoikd@LIVE.CA>
wrote:
>>> >
>>> >>Is it possible to use proc procedures in the middle of data step?
>>> >>
>>> >> The procedures can be proc means or any other procedures.
>>> >> I am not going to make any print output other than saveing output
>>> >> sas files for future use.
>>> >>
>>> >> Thanks.
>>>
>>>
>>>
|