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