From: montura on
Dynamic arrays are commonly used in SAS/SCL.

The declaration and usage would be nearly the same as fortran, but you
will need to use CLASS property arrays. This is not so easy with Base/
SAS, and with SAS/SCL I frequently use a series of three and four
dimensional arrays, all of which are resized per observation.

The programmed logic that you would use in the Data Step are 100%
transferable to SAS/SCL. Dynamic arrays are the next topic on my
series of SAS object programming, if you forward a data sample and
logic requirements I will see about using that as a primary example.

From: Mike Rhoads on
If you are going to calculate the number of years needed, it needs to be done with a macro variable in order to use it for dimensioning the array:

%let numyears=%eval(&slutaar-&startaar+1);
Array sampled{&numyears} sampled&startaar - sampled&slutaar;
sampled{aar}=1;
DROP alder;

By the way, I always like to put such macro statements outside of (prior to) DATA and PROC steps. This reduces the confusion between macro statements and other statements that need to execute within the context of a SAS step.

Better yet, use the * to dimension your array, and you don't have to worry about calculating the number of years required at all:

Array sampled{*} sampled&startaar - sampled&slutaar;


Mike Rhoads
RhoadsM1(a)Westat.com


-----Original Message-----
From: SAS(r) Discussion [mailto:SAS-L(a)LISTSERV.UGA.EDU] On Behalf Of Håkan Lane
Sent: Monday, December 14, 2009 7:31 AM
To: SAS-L(a)LISTSERV.UGA.EDU
Subject: SAS dynamic arrays

I would like to implement an array the size of which is not known a priori. Instead of declaring an implicit value for the number of elements, I wish to find this value from a variable. This can be done in other languages including Fortran.

My attempt to code this as shown below fails.

DATA libout.pdata;
SET cpr;
byear=aar-alder;
numyears=&slutaar-&startaar+1;
Array sampled{numyears} sampled&startaar - sampled&slutaar;
sampled{aar}=1;
DROP alder numyears;
IF last.pnr THEN output;
ELSE DO;
END;
RUN;

The idea is to replace a structure with one record every year that a person was in our records with their age so an array with a 1 if they were in and 0 if they weren't. The age (alder from above) is represented with a birthyear. This would quite obviously save a lot of redundant data. The issue is that we might run the program with different start and end years. That is why it would be better for them to be external constants.

Thanks in advance.

Regards,

H�kan Lane
From: Joe Matise on
No reason you would need to dimension it at all. SAS is quite smart and ca=
n
figure it out for you on the fly.

array sampled sampled:;
will take every variable starting with 'sampled' and something after it.

-Joe

On Mon, Dec 14, 2009 at 6:31 AM, H=C3=A5kan Lane <hlane(a)cls.dk> wrote:

> I would like to implement an array the size of which is not known a
> priori. Instead of declaring an implicit value for the number of
> elements, I wish to find this value from a variable. This can be done
> in other languages including Fortran.
>
> My attempt to code this as shown below fails.
>
> DATA libout.pdata;
> SET cpr;
> byear=3Daar-alder;
> numyears=3D&slutaar-&startaar+1;
> Array sampled{numyears} sampled&startaar - sampled&slutaar;
> sampled{aar}=3D1;
> DROP alder numyears;
> IF last.pnr THEN output;
> ELSE DO;
> END;
> RUN;
>
> The idea is to replace a structure with one record every year that a
> person was in our records with their age so an array with a 1 if they
> were in and 0 if they weren't. The age (alder from above) is
> represented with a birthyear. This would quite obviously save a lot of
> redundant data. The issue is that we might run the program with
> different start and end years. That is why it would be better for them
> to be external constants.
>
> Thanks in advance.
>
> Regards,
>
> H=E5kan Lane
>
From: Mary on
SAS can use the * declaration and dim function similar to the way many other languages do:

data test;
informat v1 v2 v3 v4 v5 v6;
input v1 v2 v3 v4 v5 v6;
array varray{*} v1-v6;
do i=1 to dim(varray);
put varray[i];
end;
cards;
1 2 3 4 5 6
10 20 30 40 50 60
;
run;

-Mary

--- hlane(a)CLS.DK wrote:

From: HÃ¥kan Lane <hlane(a)CLS.DK>
To: SAS-L(a)LISTSERV.UGA.EDU
Subject: SAS dynamic arrays
Date: Mon, 14 Dec 2009 13:31:22 +0100

I would like to implement an array the size of which is not known a
priori. Instead of declaring an implicit value for the number of
elements, I wish to find this value from a variable. This can be done
in other languages including Fortran.

My attempt to code this as shown below fails.

DATA libout.pdata;
SET cpr;
byear=aar-alder;
numyears=&slutaar-&startaar+1;
Array sampled{numyears} sampled&startaar - sampled&slutaar;
sampled{aar}=1;
DROP alder numyears;
IF last.pnr THEN output;
ELSE DO;
END;
RUN;

The idea is to replace a structure with one record every year that a
person was in our records with their age so an array with a 1 if they
were in and 0 if they weren't. The age (alder from above) is
represented with a birthyear. This would quite obviously save a lot of
redundant data. The issue is that we might run the program with
different start and end years. That is why it would be better for them
to be external constants.

Thanks in advance.

Regards,

Håkan Lane
From: =?iso-8859-1?b?SMOla2Fu?= Lane on
Thank you all for providing nice help. It works out a lot better now
with another change, but a problem is that sampled only is set the
last time that the person appears, captured by last.pnr. I would have
liked sampled to be set every time and then a record written only the
last time.

For example, current records of

pnr=1,aar=2001
pnr=1,aar=2002
pnr=1,aar=2003

should result in pnr=1,sampled2001=1,sampled2002=1,sampled2003=1
and not as now only in pnr=1,sampled2003=1.

How do I do that?


DATA libout.pdata;
SET cpr;
byear=aar-alder;
%let numyears=%eval (&slutaar-&startaar+1);
Array sampled{&numyears} sampled&startaar - sampled&slutaar;
%let index=aar-&startaar+1;
sampled{&index}=1;
DROP alder numyears;
IF last.pnr THEN output;
ELSE DO;
END;
RUN;

Regards,

H�kan Lane

>
>
> -----Original Message-----
> From: SAS(r) Discussion [mailto:SAS-L(a)LISTSERV.UGA.EDU] On Behalf Of
> Håkan Lane
> Sent: Monday, December 14, 2009 7:31 AM
> To: SAS-L(a)LISTSERV.UGA.EDU
> Subject: SAS dynamic arrays
>
> I would like to implement an array the size of which is not known
> a priori. Instead of declaring an implicit value for the number of
> elements, I wish to find this value from a variable. This can be
> done in other languages including Fortran.
>
> My attempt to code this as shown below fails.
>
> DATA libout.pdata;
> SET cpr;
> byear=aar-alder;
> numyears=&slutaar-&startaar+1;
> Array sampled{numyears} sampled&startaar - sampled&slutaar;
> sampled{aar}=1;
> DROP alder numyears;
> IF last.pnr THEN output;
> ELSE DO;
> END;
> RUN;
>
> The idea is to replace a structure with one record every year that
> a person was in our records with their age so an array with a 1 if
> they were in and 0 if they weren't. The age (alder from above) is
> represented with a birthyear. This would quite obviously save a lot
> of redundant data. The issue is that we might run the program with
> different start and end years. That is why it would be better for
> them to be external constants.
>
> Thanks in advance.
>
> Regards,
>
> H�kan Lane
>