DATA Step, Macro, Functions and more

Flagging using ARRAYS

Accepted Solution Solved
Reply
Frequent Contributor
Posts: 85
Accepted Solution

Flagging using ARRAYS

Hi All,

I have 15 columns named parent1,parent2..parent 15 ... My task is to check the values in each column and compare it with the column+2 values  and if value in first column=134 and value in column +2=3543 then I need to set the value as 1 else it should be zero.

Input

Parent1Parent2parent3parent4parent5parent6parent7parent8parent9parent10parent11parent12parent13parent14parent15
13254635432343524324634534265481124356547823435325325345
23436651321162343523213266735433453544765433243543256132
4351321212354311645679871341214132547567354343532423435
78798023249932556543529827879235643672443456214346

Desired Output

Parent1Parent2parent3parent4parent5parent6parent7parent8parent9parent10parent11parent12parent13parent14parent15O/pcode
132546354323435243246345342654811243565478234353253253451
234366513211623435232132667354334535447654332435432561321
43513212123543116456798713412141325475673543435324234351
787980232499325565435298278792356436724434562143460

If you look at row1 (value of parent1=132 ) and value of parent 3543 and hence in my output table o/p code is set to 1  ..... same for other rows also .. row2 (parent7=132 and parent9=3543 ) and hence it is also set as 1.

I know this can be done using array .. but some how i get an error of array index out of subscript error when trying to look ahead.

Anyhelp in any other way to solve this could be extremely helpful.

Many thanks in advance


Accepted Solutions
Solution
‎03-05-2015 08:57 AM
Respected Advisor
Posts: 3,777

Re: Flagging using ARRAYS

You can start at the first 132 and stop when FLAG is set.

Data Have;
   Input Parent1-Parent15;
   cards;
132 546 3543 23435 2432 46345 3426 548 112 4356 5478 23435 325 325 345
2343 665 132 116 23435 232 132 667 3543 3453 5447654 3324 3543 256 132
435 132 1212 3543 116 456 7987 134 1214 132 547567 3543 435 324 23435
787 980 2324 99 325 565 4352 982 7879 2356 4367 244 3456 214 346
;;;;
   run;
proc print;
  
run;
data flagged;
   set have;
   array _p
  • parent:;
  •    l = whichn(132,of _p
  • );
  •    if l then do i = l to dim(_p)-2 until(flag);
          if _p eq 132 and _p[i+2] eq 3543
            
    then flag=1;
            
    else flag=0;
         
    end;
      
    else flag=0;
      
    run;
    proc print;
      
    run;

    3-5-2015 7-55-11 AM.png

    View solution in original post


    All Replies
    Super User
    Super User
    Posts: 7,401

    Re: Flagging using ARRAYS

    Its likely you are with the +2 going past the end of the array, so on element max of array - 1 it will be looking for max of array + 1 which is the error out of bounds.  Check your loops.

    You could of course transpose your data to vertical structure and then use where clauses or SQL exists.  Can't provide code right now.

    Super Contributor
    Posts: 336

    Re: Flagging using ARRAYS


    Data Have;
      Infile Datalines Delimiter='09'x;
      Input (Parent1-Parent15) (:Best8.);
      Datalines;
    132 546 3543 23435 2432 46345 3426 548 112 4356 5478 23435 325 325 345
    2343 665 132 116 23435 232 132 667 3543 3453 5447654 3324 3543 256 132
    435 132 1212 3543 116 456 7987 134 1214 132 547567 3543 435 324 23435
    787 980 2324 99 325 565 4352 982 7879 2356 4367 244 3456 214 346
    ;
    Run;

    Data Want (Drop=i);
      Set Have;
      Array P{*} P:;
      Do i=1 To Dim(P)-2;
        O_Code=Max(O_Code,IfN(P{i}=132 & P{i+2}=3543,1,0),0);
      End;
    Run;

    Contributor
    Posts: 37

    Re: Flagging using ARRAYS

    data

    want

    ;

    set

    have

    ;

    array arr1 parent1 - parent15;

    opcode = 0;

    do i = 1 to 13 ;

    if arr1(i) = 132 and arr1(i+2) = 3543 then opcode = 1;

    end;

    run;

    Solution
    ‎03-05-2015 08:57 AM
    Respected Advisor
    Posts: 3,777

    Re: Flagging using ARRAYS

    You can start at the first 132 and stop when FLAG is set.

    Data Have;
       Input Parent1-Parent15;
       cards;
    132 546 3543 23435 2432 46345 3426 548 112 4356 5478 23435 325 325 345
    2343 665 132 116 23435 232 132 667 3543 3453 5447654 3324 3543 256 132
    435 132 1212 3543 116 456 7987 134 1214 132 547567 3543 435 324 23435
    787 980 2324 99 325 565 4352 982 7879 2356 4367 244 3456 214 346
    ;;;;
       run;
    proc print;
      
    run;
    data flagged;
       set have;
       array _p
  • parent:;
  •    l = whichn(132,of _p
  • );
  •    if l then do i = l to dim(_p)-2 until(flag);
          if _p eq 132 and _p[i+2] eq 3543
            
    then flag=1;
            
    else flag=0;
         
    end;
      
    else flag=0;
      
    run;
    proc print;
      
    run;

    3-5-2015 7-55-11 AM.png
    Respected Advisor
    Posts: 3,777

    Re: Flagging using ARRAYS

    This version uses WHICHN and a little trick to "skip" through the list of variables.

    Data Have;
       Input Parent1-Parent15;
       cards;
    132 546 3543 23435 2432 46345 3426 548 112 4356 5478 23435 325 325 345
    2343 665 132 116 23435 232 132 667 3543 3453 5447654 3324 3543 256 132
    435 132 1212 3543 116 456 7987 134 1214 132 547567 3543 435 324 23435
    787 980 2324 99 325 565 4352 982 7879 2356 4367 244 3456 214 346
    787 980 2324 99 325 565 4352 982 7879 2356 4367 244 3456 214 132
    ;;;;
       run;
    proc print;
      
    run;
    data flagged;
       set have;
       array _p
  • parent:;
  •    flag=0;
       l = whichn(
    132,of _p
  • );
  •    do i = l+2 by 0 while(l);
          if i le dim(_p) then if _p eq 3543 then do;
             flag=
    1;        
            
    leave;
            
    end;
         
    call missing(_p);
          l = whichn(132,of _p
  • );
  •       i = l + 2;
         
    end;
      
    call stdize('missing=',132,'none', of _p
  • );
  •    run;
    proc print;
      
    run;

    3-5-2015 11-51-13 AM.png
    Respected Advisor
    Posts: 3,124

    Re: Flagging using ARRAYS

    This one is just for fun, but the efficiency is guaranteed:

    Data Have;

         Input Parent1-Parent15;

         cards;

    132 546 3543 23435 2432 46345 3426 548 112 4356 5478 23435 325 325 345

    2343 665 132 116 23435 232 132 667 3543 3453 5447654 3324 3543 256 132

    435 132 1212 3543 116 456 7987 134 1214 132 547567 3543 435 324 23435

    787 980 2324 99 325 565 4352 982 7879 2356 4367 244 3456 214 346

    ;;;;

    run;

    data want;

         set have;

         array p parent1-parent15;

         flag=prxmatch(cat('/',put(132,rb8.),'(.|\n){8}?',put(3543,rb8.),'/o'), peekclong(addrlong(p(lbound(p))),8*dim(p)))>0;

    run;

    ☑ This topic is SOLVED.

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

    Discussion stats
    • 6 replies
    • 439 views
    • 8 likes
    • 6 in conversation