LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (August 2009, week 2)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:   Thu, 13 Aug 2009 11:49:15 -0400
Reply-To:   "Gerstle, John (CDC/CCID/NCHHSTP)" <yzg9@CDC.GOV>
Sender:   "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:   "Gerstle, John (CDC/CCID/NCHHSTP)" <yzg9@CDC.GOV>
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)
In-Reply-To:   <129a50e0908130823r37561f40l970e38edc16a6084@mail.gmail.com>
Content-Type:   text/plain; charset=us-ascii

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. >>> >>> >>>


Back to: Top of message | Previous page | Main SAS-L page