DATA Step, Macro, Functions and more

Question about a simple array

Accepted Solution Solved
Reply
Contributor
Posts: 67
Accepted Solution

Question about a simple array

Hello! I have an array I would like to compute.

So there are 20 traumas, and 19 possible ages you can endorse each trauma (ages 0 - 18). I would like to  know whether someone endorsed a trauma at each age, regardless of which kind of trauma and then sum up the # of years they endorsed a trauma)  When I do this for 3 traumas (traumas gt1, gt3, gt5) it looks like this:

data new;

     set old;


array gt1a[19] gt1a0-gt1a18;

    array gt3a[19] gt3a0- gt3a18;

    array gt5a[19] gt5a0 - gt5a18;

    array gtnew[19] gta0 - gta18;

    do i = 1 to 19;

        if (gt1a= 1 | gt3a = 1 | gt5a= 1) then gtnew=1;

    end;

    if age ne . then duration = sum(of gta0 - gta18);

run;

Here, the "a0" through "a18" indicates that it's age 0 ,..., age18.

How can I do this for all 20 traumas? gt1 through gt20? Without having to type 20 array statements? Thanks!


Edit: sorry! Here is what the data would look like for ID #5, who enrolled in the study at age 1.5. We see that he experienced trauma1 at age 1 and 2, and experienced trauma2 at age 0 and 1. the rest of the entries are missing, i.e., he did not experience trauma then.


ID age gt1a0  gt1a1 gt1a2 gt1a3 .... gt1a18 gt2a0 gt2a1 gt2a2 gt2a3 gt2a4 , ... , gt2a18 gt3a0,...,gt3a18 gt4a0 ,.........., gt20a0 gt20a1 gt20a2 gt20a3 gt20a4 , ..., gt20a18

5  6         .       1       1      .             .          1      1        .        .       .                 .           .           .          .                       .          .        .        .           .                  .

17  2       1          1      1     .             .           .        .      .        .       1                 .           .          .           .                       .          .       .          .          .                    .

This data is in wide format so I am creating a new array of variables called gta0 - gta18; each variable will be '1' if child experienced ANY trauma at that age

so for ID # 5:


ID age gta0 gta1 gta2 gta3 gta4 , ....., gta18 duration

5   6       1    1       1       .      .                .      3

17   2     1    1       1      .       1                .      4



Since ID#5 experienced trauma 2 at age 0, he has a '1' for gta0. since he experienced traumas 1 and 2 at age 1, he gets a 1 for gta1. since he experienced trauma1 at age 2, he gets a 1 for gta2. since he didn't experience trauma at any other age, he has missing for those.


Since ID #17 experienced trauma 1 at age 0,1 and 2,i .e, has a 1 for gt1a0 through gt1a2, he has a '1' for gta0 through gta2. Since he endorsed trauma2 at age 4, he now has gta4=1.


Since this is wide format data, I'm still going to keep all the other gt1a0 through gt20a18 variables in the data set. I've just typed what I want the new array to give us. Does this help?

I am trying to figure out who is a data error (So ID #6 is ok, because he enrolled at age 6 and endorsed trauma up til age 2. However, ID #17 enrolled at age 2 but endorsed a trauma at age 4. this is problematic and this is what I am exploring).

Hope this is helpful, please let me know if it is not or needs more clarification Smiley Happy


Accepted Solutions
Solution
‎05-20-2014 04:43 PM
PROC Star
Posts: 7,356

Re: Question about a simple array

I'm really not sure that I understand exactly what you are trying to do, but I think that the following might come close:

%let maxitem=3;

%let nitems=3;

data old;

  input ID age gt1a0-gt1a&maxitem. gt2a0-gt2a&maxitem. gt3a0-gt3a&maxitem.;

  cards;

5  6 . 1 1 . 1 1 . . . . . .

17 2 1 1 1 . . . . . . . . 1

;

data new (drop=i j);

  set old;

  array gtin(1:&nitems.,0:&maxitem) gt1a: gt2a: gt3a:;

  array _dur(&nitems);

  array trauma(0:&maxitem);

  do i=1 to &nitems.;

    call missing(trauma(i));

  end;

  do i=1 to &nitems.;

    call missing(_dur(i));

    do j=0 to &maxitem.;

      _dur(i)=sum(_dur(i), gtin(i,j));

      if gtin(i,j) eq 1 then trauma(j)=1;

    end;

  end;

  duration=sum(of _dur(*));

run;

View solution in original post


All Replies
Super User
Posts: 17,750

Re: Question about a simple array

Sample input and output data please.

Contributor
Posts: 67

Re: Question about a simple array

Just added some more info Smiley Happy

Super User
Posts: 10,466

Re: Question about a simple array

I think if you provide a more complete description or possibly several rows of  data this may be easier to answer. Especially with a naming convention involving GT1 GT3 GT5.

My gut feeling is the data probably should be restructured to be more of an ID, single age and whether the trauma was at that age first.

Contributor
Posts: 67

Re: Question about a simple array

Good idea, just added some more information for two sample cases.

Respected Advisor
Posts: 3,124

Re: Question about a simple array

Ah, if your variables lay the way you presented, you can try the following:

data want;

set have;

array _age(0:18) _temporary_;

array gt gt1a0--gt20a18;

do over gt;

_age(mod(_I_,19))=ifn(gt=1,1,_age(mod(_I_,19)));

end;

duration=sum(of _age(*));

call missing(of _age(*));

run;

The key is to line it up with your temp array, when it hits '1', stay at '1'.

Good Luck,

Haikuo

update: have to reset the temp array for each implicit loop.

Solution
‎05-20-2014 04:43 PM
PROC Star
Posts: 7,356

Re: Question about a simple array

I'm really not sure that I understand exactly what you are trying to do, but I think that the following might come close:

%let maxitem=3;

%let nitems=3;

data old;

  input ID age gt1a0-gt1a&maxitem. gt2a0-gt2a&maxitem. gt3a0-gt3a&maxitem.;

  cards;

5  6 . 1 1 . 1 1 . . . . . .

17 2 1 1 1 . . . . . . . . 1

;

data new (drop=i j);

  set old;

  array gtin(1:&nitems.,0:&maxitem) gt1a: gt2a: gt3a:;

  array _dur(&nitems);

  array trauma(0:&maxitem);

  do i=1 to &nitems.;

    call missing(trauma(i));

  end;

  do i=1 to &nitems.;

    call missing(_dur(i));

    do j=0 to &maxitem.;

      _dur(i)=sum(_dur(i), gtin(i,j));

      if gtin(i,j) eq 1 then trauma(j)=1;

    end;

  end;

  duration=sum(of _dur(*));

run;

Contributor
Posts: 67

Re: Question about a simple array

thank yoU Smiley Happy

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 7 replies
  • 411 views
  • 6 likes
  • 5 in conversation