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
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;
Define sequential order please?
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;
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.
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 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.