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

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

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

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