0

I would like to be able to execute a do loop for a non-sequential set of values. The way I have written this code runs a new data step for each value - so therefore the end product is a data table with a column added for the final value of the do loop only. What I want is for the the values in the varlst to loop through the if/then statements - thereby adding multiple columns to the table - without executing a new data step each time (which only results in adding one final column to the table).

INPUT DATA

DATA have;
INPUT id order Q3 Q5 Q6 Q50 Q75 Q102;
DATALINES;
 1  1  2 0  7 2 2 0
 1  2  3 0  5 5 3 0
 3  1  6 1  7 2 7 1
 3  2  6 0  7 5 7 0
 6  1  3 1  4 7 7 2
 6  2  5 2  7 7 7 1
 7  1  3 5  6 5 3 0
 7  2  4 1  7 5 2 1
 9  1  4 1  6 5 6 1
 9  2  1 3  5 7 5 0
; 
run;

/********/

 %macro test;
    %let varlst=2 3 5 6 50 75 102 /*more values*/;
    %do i=1 %to %sysfunc(countw(&varlst));
    %let value=%scan(&varlst,&i);
    data want;
    set have;
    by id order;
    if Q&value ne lag(Q&value) and not first.id then do; 
            Q&value.Equal = 0; 
                end;
        if Q&value=lag(Q&value) and not first.id then do;
        Q&value.Equal = 1;
                end;
                %end;
       run;
    %mend;
    %test;

/**********/ OUTPUT

id  order   Q3  Q5  Q6  Q50  Q75 Q102 Q102Equal
1   1       2    0   7   2    2   0     .
1   2       3    0   5   5    3   0     1
3   1       6    1   7   2    7   1     .
3   2       6    0   7   5    7   0     0
6   1       3    1   4   7    7   2     .
6   2       5    2   7   7    7   1     0
7   1       3    5   6   5    3   0     .
7   2       4    1   7   5    2   1     0
9   1       4    1   6   5    6   1     .
9   2       1    3   5   7    5   0     0
green2010
  • 21
  • 2
  • Can you better explain what you are trying to do? Your code is written to generate many data steps that will overwirte the same dataset over and over again. If you just want to use a data step DO loop for a set of values then that is directly supported by the data step and does not require any macro logic. `do value = 2,3,5,6,50,75,102;` – Tom Jun 03 '16 at 20:33
  • Post example input and output data. It is difficult to tell if you have many variables or a single variable with many values. – Tom Jun 03 '16 at 20:38
  • I've made edits to the post above to display some of the input data and the output. What I am trying to do is determine whether two coders (order 1 and 2) gave the same rating on questions (Q3, Q5, etc.) for each survey (ID). That is why I am using the lag function. I was trying to write a macro for this task because I have quite a few questions to compare (more than are represented here) and I didn't want to have to type out that many lines of code (to reduce error). As the output shows, I only get output for the final question comparison the way it is written now. Thanks for your help. – green2010 Jun 03 '16 at 21:44

1 Answers1

0

Why don't you try using PROC COMPARE?

data have ;
  input id  order   Q3  Q5  Q6  Q50  Q75 Q102;
cards;
1   1       2    0   7   2    2   0     .
1   2       3    0   5   5    3   0     1
3   1       6    1   7   2    7   1     .
3   2       6    0   7   5    7   0     0
6   1       3    1   4   7    7   2     .
6   2       5    2   7   7    7   1     0
7   1       3    5   6   5    3   0     .
7   2       4    1   7   5    2   1     0
9   1       4    1   6   5    6   1     .
9   2       1    3   5   7    5   0     0
;;;;

proc compare
   data=have(where=(order=1))
   compare=have(where=(order=2)) 
   outdiff out=want 
;
  id id ;
  var q: ;
run;
Tom
  • 47,574
  • 2
  • 16
  • 29