BookmarkSubscribeRSS Feed
kk13
Calcite | Level 5

I would like to find out if array (a1-a8) contains 1 or 0 using the date1-date8 array.  The check1 to check2 provides the dates that I need to look at.  For id=1, I need to look at if the dates are within check1<=dates{i}<=check2.  Therefore, date1 through date5 are within check1 and check2.  I need to check if a1 through a5 contains any 1.  If yes, then HAS=1.  If a1 through a5 are all zeros, then HAS=0.  If a1 through a5 are some zeros and some missing, then HAS is missing. 

 

data z;

input id a1-a8 date1-date8 check1 check2;

datalines;

1 0 0 1 1 . . . . 15 15 16 16 17 18 18 20 11 17

2 . . 1 1 0 1 1 1 14 16 17 18 19 21 22 24 8 18

3 . . . 1 1 1 1 1 14 15 17 17 18 19 21 22 16 23

4 0 0 0 0 0 1 1 1 13 15 18 18 21 21 23 23 10 18

;

data want;

input id a1-a8 b1-b8 check1 check2 HAS;

datalines;

1 0 0 1 1 . . . . 15 15 16 16 17 18 18 20 11 17 1

2 . . 1 1 0 1 1 1 14 16 17 18 19 21 22 24 8 18 1

3 . . . 1 1 1 1 1 14 15 17 17 18 19 21 22 16 23 1

4 0 0 0 0 0 1 1 1 13 15 18 18 21 21 23 23 10 18 0

5 0 0 . . 1 1 1 1 10 11 11 13 13 17 17 18 9 11 .

;

 

I found jth dimension where dates is within check1 and check2.  I need to check if a1 through a jth contains any 0 or if a1 through a jth are all equal to 0.

 

data z1;

set z;

array a a1-a8;

array date date1-date8;

do i=1 to dim(a);

if check1<=date{i}<=check2 then do;

 

j=i;

end;

end;

run;

 

2 REPLIES 2
japelin
Rhodochrosite | Level 12

How is this code?

 

data z1(drop=i j:);
  set z;
  array a a1-a8;
  array date date1-date8;
  do i=1 to dim(a);
    if check1<=date{i} and j_start=. then do;
      j_start=i;
    end;
    if check1<=date{i}<=check2 then do;
      j_end=i;
    end;
  end;
  has=0;
  do i=j_start to j_end;
    if a{i}=1 then has=1;
    else has=has+a{i};
    if has=1 then leave;
  end;
run;
mkeintz
PROC Star

@kk13 wrote:

I would like to find out if array (a1-a8) contains 1 or 0 using the date1-date8 array.  The check1 to check2 provides the dates that I need to look at.  For id=1, I need to look at if the dates are within check1<=dates{i}<=check2.  Therefore, date1 through date5 are within check1 and check2.  I need to check if a1 through a5 contains any 1.  If yes, then HAS=1.  If a1 through a5 are all zeros, then HAS=0.  If a1 through a5 are some zeros and some missing, then HAS is missing. 

 

You can simplify the code by this approach:

  1. Initialize has=0
  2. Loop through the eligible dates
    1. If the corresponding A has a 1, set HAS=1 and exit the loop
    2. If the corresponding A has a ., increment the counter NMISS
  3. At the end of the loop, if HAS is not=1 but NMISS>0 then set HAS=.
  4. So HAS will stay at zero only if (1) no 1's were found, and (2) no missings were found - i.e. only 0's were encountered
data z;
  input id a1-a8 date1-date8 check1 check2;
datalines;
1 0 0 1 1 . . . . 15 15 16 16 17 18 18 20 11 17
2 . . 1 1 0 1 1 1 14 16 17 18 19 21 22 24 8 18
3 . . . 1 1 1 1 1 14 15 17 17 18 19 21 22 16 23
4 0 0 0 0 0 1 1 1 13 15 18 18 21 21 23 23 10 18
;

/*I need to check if a1 through a5 
  -contains any 1.  If yes, then HAS=1.  
  If a1 through a5 are all zeros, then HAS=0.  
   If a1 through a5 are some zeros and some missing, then HAS is missing. */

 
data want (drop=i nmiss);
  set z;
  array a   {8} a1-a8;
  array dat {8} date1-date8;

  has=0;
  do i=1 to 8 while (dat{i}<=check2  and has=0);
    if dat{i}>=check1 then do;
      if a{i}=1 then has=1; else
      if a{i}=. then nmiss=sum(nmiss,1);      
    end;
  end;
  if has^=1 and nmiss>0 then has=.;
run;

 

Notes:

  1. The "while" expression does two things:
    1. It stops the loop when a date is reached that is greater than CHECK2 
    2. Or it stops the loop once HAS=1

  2. Note all dates less than CHECK1 are in the loop, but the internal DO group is not applied for them.

  3. IMPORTANT: This code assume DATE1 through DATE8 are in non-descending order.
--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 807 views
  • 0 likes
  • 3 in conversation