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

Hi everyone,

 

I have a character variable that looks like this:

var x

004101010100100111121001        
122112102102111111212112          
111011111111111111111111              
111112111111111111111111              
000043211111111111111111            

 

reading it from left to right, my main aim is to flag (0 or 1) for accounts that has the varx that are NOT in sequential order as shown below:

 

var x

004101010100100111121001        1
122112102102111111212112          1
111011111111111111111111              0
111112111111111111111111              0
000043211111111111111111            1

 

Do you guys have any idea of how I can do this? Appreciate the help. Thanks in advance

1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

Hi @nanmz and welcome to the SAS Support Communities!

 

If "jumps" by more than 1 in either direction are to be flagged, try this:

 

data have;
input x $50.;
cards;
004101010100100111121001
122112102102111111212112
111011111111111111111111
111112111111111111111111
000043211111111111111111
;

data want(drop=_i);
set have;
flag=0;
array _d[0:1] _temporary_;
_d[1]=input(char(x,1),1.);
do _i=2 to length(x);
  _d[mod(_i,2)]=input(char(x,_i),1.);
  if abs(_d[1]-_d[0])>1 then do;
    flag=1;
    leave;
  end;
end;
run;

View solution in original post

4 REPLIES 4
PeterClemmensen
Tourmaline | Level 20

Define sequential order please?

FreelanceReinh
Jade | Level 19

Hi @nanmz and welcome to the SAS Support Communities!

 

If "jumps" by more than 1 in either direction are to be flagged, try this:

 

data have;
input x $50.;
cards;
004101010100100111121001
122112102102111111212112
111011111111111111111111
111112111111111111111111
000043211111111111111111
;

data want(drop=_i);
set have;
flag=0;
array _d[0:1] _temporary_;
_d[1]=input(char(x,1),1.);
do _i=2 to length(x);
  _d[mod(_i,2)]=input(char(x,_i),1.);
  if abs(_d[1]-_d[0])>1 then do;
    flag=1;
    leave;
  end;
end;
run;
nanmz
Fluorite | Level 6

Hi FreelanceReinhard,

 

This worked out great btw! Many thanks! 

 

Having said that, I'm just trying to understand the logic of the code a bit better. 

 

_d[0:1] _temporary_;
_d[1]=input(char(x,1),1.);
do _i=2 to length(x);
  _d[mod(_i,2)]=input(char(x,_i),1.);

why did you create temporary variables in order to get the desired output? Thanks in advance.

FreelanceReinh
Jade | Level 19

You're welcome.


@nanmz wrote:

why did you create temporary variables in order to get the desired output?


Good question. My previous approach was:

 

data want(drop=_i);
set have;
flag=0;
do _i=2 to length(x);
  if abs(input(char(x,_i),1.)-input(char(x,_i-1),1.))>1 then do;
    flag=1;
    leave;
  end;
end;
run;

Obviously, this is simpler code. What I didn't like about it was that it extracts most of the digits twice. More precisely: For a digit string of length n it evaluates 2n−2 expressions of the form input(char(...)...), as opposed to n with the version using the temporary array. So, the intention was to provide (hopefully) more efficient code, but I haven't measured its performance yet. Of course, if your HAVE dataset is small and the strings are short, there will be no significant performance difference, if any.

 

 

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 4 replies
  • 775 views
  • 0 likes
  • 3 in conversation