BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Chauncy
Fluorite | Level 6

Now I have a simplified example.

Snipaste_2022-09-01_17-33-37.png

As in the picture above, there are two variables. The variable y is the original data and variable x is the order variable I want. 

You can see, y has a cretain regular pattern that most of its data follow 'cc bb aa cc bb aa..'(Notice that obs 11, for some reason, there's only one 'a'. And that's the only unsual pattern we considered.). 

So, when I want a sequence for every two different y-values a number, it becomes a problem.

I try to use RETAIN statment, but as a fresh hand, I really need some support.

Thanks for your reading, and hope you can do me a favor.

1 ACCEPTED SOLUTION

Accepted Solutions
andreas_lds
Jade | Level 19

Posting the code you have (using the little-running-man icon) would allow us to suggest code that fixes what you have, instead of posting something new.

 

x needs to be incremented each second time that the value of y changes. So, you need to retain: x, the last value of y and another variable, i call it c holding the number of changes.

 

data want;
   set have;
   retain x c _y;
   
   if _n_ = 1 then do;
      x = 1;
      c = 0;
   end;
   else do;
      if _y ne y then do;
         c = c + 1;
         
         if c = 2 then do;
            x = x + 1;
            c = 0;
         end;
      end;
   end;
   
   _y = y;
run;

View solution in original post

4 REPLIES 4
andreas_lds
Jade | Level 19

Posting the code you have (using the little-running-man icon) would allow us to suggest code that fixes what you have, instead of posting something new.

 

x needs to be incremented each second time that the value of y changes. So, you need to retain: x, the last value of y and another variable, i call it c holding the number of changes.

 

data want;
   set have;
   retain x c _y;
   
   if _n_ = 1 then do;
      x = 1;
      c = 0;
   end;
   else do;
      if _y ne y then do;
         c = c + 1;
         
         if c = 2 then do;
            x = x + 1;
            c = 0;
         end;
      end;
   end;
   
   _y = y;
run;
Chauncy
Fluorite | Level 6

Thank you for your help! Your code really does what I needed. Comparing y and _y(previous y value) is a new idea for me. This gave me a deeper understanding of the underlying mechanism of data-step and retian statement. 

FreelanceReinh
Jade | Level 19

Hello @Chauncy and welcome to the SAS Support Communities!

 

Once you have learned about BY-group processing, the sum statement and the MOD function, you will be able to implement the solution presented by andreas_lds in a more concise DATA step:

data want(drop=c);
set have;
by y notsorted;
if first.y then do;
  c+1;
  x+mod(c,2);
end;
run;

At the first observation of each group of equal y values ("if first.y ..."), the counter c is incremented ("c+1;"). If the value of c is odd (1, 3, 5, ...), variable x is incremented by 1 (=mod(c,2)) as well, otherwise its value doesn't change because the increment mod(c,2) is zero. For both c and x the initial values are 0 and they are retained by virtue of the sum statement. As variable c is not needed in dataset WANT, I have dropped it using the DROP= dataset option (but you may want to see it for better understanding).

 

Chauncy
Fluorite | Level 6

Thank you for your help ! Your code works, of course! The notsorted option is brand new for me, though I have learned BY statement. Looks like it could simplify many problems.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 4 replies
  • 645 views
  • 2 likes
  • 3 in conversation