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 (September 2008, week 2)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Thu, 11 Sep 2008 12:56:51 +0100
Reply-To:     cherish k <hawks_cherish@YAHOO.CO.IN>
Sender:       "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:         cherish k <hawks_cherish@YAHOO.CO.IN>
Subject:      Re: How to declare macro variable within datastep and using it
Comments: To: Scott Bass <sas_l_739.at.yahoo.dot.com.dot.au@PESTO.CC.UGA.EDU>
In-Reply-To:  <48c8f9f5$0$32033$5a62ac22@per-qv1-newsreader-01.iinet.net.au>
Content-Type: text/plain; charset=utf-8

My requirements are as follows.

I have a big dataset with array size of 8000 elements and close to 200000 records. I need to do some data manipulations using some records from the big dataset. The record number to which manipulations have to be done comes from another dataset (assume the record to be pointed comes from that dataset). Though I have like 8000 elements in it, I need to access a few of the elements only and the elements id is not static which means for record 1 i may have to look into element 10,20,50 and for record 2 i may have to look into 30,80,100 and so forth.

I was thinking if I set the whole array of the big file then run time will be huge, so I wanted to set the huge array file with only the element i require and the moment i end the read i will drop it so that the output PDV doesnt contain all the array elements.

The example I quoted is just for reference.

data chk; do i = 1 to 10; array m(10); do j = 1 to 10; m(j) = round(ranuni(0)*100); end; output; end; run;

data chk1(drop = i); do i = 1 to 10; val = round(ranuni(0)*5 + 1); rec_num = i; output; end; run;

data chk2; set chk1; p = rec_num; %let arr_ele = val; set chk(keep = m%eval(&arr_ele)) point = p; req_val = m%eval(&arr_ele); drop m%eval(&arr_ele); run;

In the above datasets chk1 has the file pointer to be used to access chk file and also the array element to be accessed which is val. So i need to use both these information to access chk file.

One simple thing to do is just set the entire array and use m(val) to get the element. But i will have to set the entire array which i think will take more memory and also more time. So i was thinking how to keep only the one element I need. Any thoughts?

Scott Bass <sas_l_739.at.yahoo.dot.com.dot.au@PESTO.CC.UGA.EDU> wrote: Hi Cherish,

Can you tell us exactly what you're trying to do? Not in code, esp. the intermix of sas and macro statements below, but in pseudocode/easy to understand terms.

Regarding your use of macro, you're confused about how SAS compiles macro code. Read this section of the doc: http://support.sas.com/onlinedoc/913/getDoc/en/mcrolref.hlp/a002047087.htm http://support.sas.com/onlinedoc/913/getDoc/en/mcrolref.hlp/a001071821.htm http://support.sas.com/onlinedoc/913/getDoc/en/mcrolref.hlp/a001071824.htm

It's not long - should take about 15-20 mins. Don't post back until you've read these links, esp. the last one :) lol.

Basically, SAS resolves your macro code during the compilation phase of the program, then executes the resolved code. Your intermixing of SAS and macro code below is never going to work. At this point in your learning, think of macro as a very fast typist, generating code for you, that then gets compiled and processed by SAS.

My gut feeling is you could do what you want without macro, but I don't know what you want to do.

See also inline comments below.

Cheers, Scott

"cherish k" wrote in message news:48568.75100.qm@web94107.mail.in2.yahoo.com... >I tried this method too... > > data chk; > do i = 1 to 10; > array m(10); > do j = 1 to 10; > m(j) = round(ranuni(0)*100); > val = round(ranuni(0)*5 + 1); > end; > output; > end; > run; > > %macro chk_pnt(pnt,var_ind); > do l = &pnt to &pnt; > set chk(keep = m&var_ind) point = l; > req_val = m&var_ind; > drop m&var_ind; > end; > %mend chk_pnt; >

This macro %runpt doesn't add any value - it doesn't have any macro code, other than the call to %chk_pnt, which could just be in open code.

> %macro runpt; > > data chk1; > set chk(keep = val); > p = _n_; > %chk_pnt(p,val); > run;

This data step would resolve to:

data chk1; set chk(keep=val); p = _n_; do l = p to p; set chk(keep=mval) point = l; req_val = mval; drop mval; end; run;

And your %chk_pnt macro isn't really adding much - even if you did want this resolved code (which I'm sure you don't), you could have just typed this code in. You're not using macro to generate any dynamic code for compilation by the SAS compiler.

> > %mend runpt; > > %runpt; > > Not sure why its not working...its able to resolve &pnt but not &var_ind > (I tried this by giving a static array variable like m3 instead of > m&var_ind to see if &pnt is getting resolved). > > Can somebody tell me where the problem is? > > Thanks > Cherish > > Joe Matise wrote: You don't. :) > > If I correctly understand what you're doing, this should do it fairly > easily: > > data chk; > do i = 1 to 10; > array m(10); > do j = 1 to 10; > m(j) = round(ranuni(0)*100); > val = round(ranuni(0)*5 + 1); > end; > output; > end; > run; > > options mprint symbolgen; > > data chk1; > set chk(keep = val); > setstatement = cats('set chk(keep=m',val,') point=p; if _n_ = (',_n_,') > then req_val = m',val,'; drop m',val,';'); > run; > > proc sql noprint; > select setstatement into :sets separated by ' ' from chk1; > quit; > > data chk2; > set chk; > &sets; > keep val req_val; > run; > > > Takes one more pass over the dataset, but you could do it as a view > probably, so it shouldn't be that bad unless you're talking millions of > records (with just the one variable). If you don't have the if _n_ = _n_ > (or p, your choice) you end up with always whichever is the last val value > for whatever reason, due to how the set statement inside a datastep > operates. > > -Joe > > > On Wed, Sep 10, 2008 at 11:15 PM, cherish k > wrote: > data chk; > do i = 1 to 10; > array m(10); > do j = 1 to 10; > m(j) = round(ranuni(0)*100); > val = round(ranuni(0)*5 + 1); > end; > output; > end; > run; > > data chk1; > set chk(keep = val); > p = _n_; > %let arr_ele = val; > set chk(keep = m%eval(&arr_ele)) point = p; > req_val = m%eval(&arr_ele); > drop m%eval(&arr_ele); > run; > > Obviously this doesn't work. I need to read the val for each element and > corrsponding array element i have to pick. Similarly i have to do it for > each record. I dont want to keep the entire array and then read by using > m(val) as the array size is huge. Can you please suggest a way to declare > a macro variable and then use it within data step. > > Thanks > Cherish > > --------------------------------- > Unlimited freedom, unlimited storage. Get it now > > > > > > > --------------------------------- > Get an email ID as yourname@ymail.com or yourname@rocketmail.com. Click > here.

--------------------------------- Unlimited freedom, unlimited storage. Get it now


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