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

Hello

I have a data set with char field that contain 6 figures 1/0.

I want to identify the following pattern (If this pattern then Indicator=1 else 0).

Block A- block of '1's in the right side

In the right side there will be continuous of one or several '1's and last number must be 1

Block B- block of '0's in the left side of block A

There can be one zero or multiple zeros in consecutive

Block C- block of '1's in the left side of block A

There can be one '1' or multiple '1's in consecutive

examples:

010101 -This pattern meet the criteria because Block A-1  Block B-0 Block C-1

000001--This pattern doesn't meet the criteria

000011--This pattern doesn't meet the criteria

101101-This pattern meet the criteria because Block A-1  Block B-0 Block C-11

101001-This pattern meet the criteria because Block A-1  Block B-00 Block C-1

010011-This pattern meet the criteria because Block A-11  Block B-00 Block C-1

 

What is the way to recognize this pattern?

Data have;
input X $;
cards;
010101 
000001
000011
000111
001111
011111
111111
110011
110111
111001
100001
001001
001011
010011
101001
101101
;
Run;

 

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User
Data have;
input X $;
cards;
010101 
000001
000011
000111
001111
011111
111111
110011
110111
111001
100001
001001
001011
010011
101001
101101
;
Run;
data want;
 set have;
 y=prxchange('s/0+/0/',-1,x);
 z=prxchange('s/1+/1/',-1,y);
 Indicator=ifn(find(z,'101'),1,0);
 drop y z;
 run;

View solution in original post

18 REPLIES 18
Ksharp
Super User
Data have;
input X $;
cards;
010101 
000001
000011
000111
001111
011111
111111
110011
110111
111001
100001
001001
001011
010011
101001
101101
;
Run;
data want;
 set have;
 y=prxchange('s/0+/0/',-1,x);
 z=prxchange('s/1+/1/',-1,y);
 Indicator=ifn(find(z,'101'),1,0);
 drop y z;
 run;
Ronein
Meteorite | Level 14

Thanks

May you please explain 

y=prxchange('s/0+/0/',-1,x);

 

Ksharp
Super User
It is changing any continuous 0s (next to each other) to a single 0.
E.X.
10001 ->101
001 -> 01

So does
z=prxchange('s/1+/1/',-1,y);
change 1s to 1 .
Ronein
Meteorite | Level 14
What is the meaning of "-1" in the formula?
Ksharp
Super User
That means replace 0s to a single 0 any times as possible,
If it was 1 that means replace only one time.
i.e.
00010001 ->010001
Amir
PROC Star

Hi,

 

Thanks for supplying the input data in a data step. Please supply the expected output data in a data step too.

 

Please also clarify the following if the examples "000001" & "000011" don't meet the criteria because they do not satisfy Block C or is it something else?

 

 

Thanks & kind regards,

Amir.

Ronein
Meteorite | Level 14
"000001"
"000011"
They don't meet the criteria of block C (block C doesn't exist for them)
Ksharp
Super User
/*
Sorry. 
I found a problem in my code.
if you want 010100 be NOT matched, try this one:
*/

Data have;
input X $;
cards;
010101
010100
;
Run;
data want;
 set have;
 y=prxchange('s/0+/0/',-1,x);
 z=prxchange('s/1+/1/',-1,y);
 Indicator=ifn(prxmatch('/101$/',strip(z)),1,0);
 drop y z;
 run;
yabwon
Onyx | Level 15

You already have an answer but, just for fun, one more:

Data have;
input X $;
cards;
010101 
000001
000011
000111
001111
011111
111111
110011
110111
111001
100001
001001
001011
010011
101001
101101
101100
;
Run;

data want;
  set have;
    marker = 
        mod(X,2) /* not ends with 0 */               
        * 
        (countw(X,"0","B") > 1) /* has at least 2 sequences of 1s (counting from right) */
    ;
run;
proc print;
run;

 

{EDIT:}

Of course if zeros on right aren't a problem (e.g., 010110 should be marked) then it reduces just to:

marker = (countw(X,"0","B") > 1);

 

{EDIT 2:}

To avoid ugly "types conversion" note in the log, the MOD() can be replaced with CHAR() function:

    marker = 
        char(X,6) = "1" /* not ends with 0 */               
        * 
        (countw(X,"0","B") > 1) /* has at least 2 sequences of 1s (counting from right) */
    ;

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Ronein
Meteorite | Level 14
The rule is that if there is 1( or multiple 1's) and then 0( or multiple 0) and then 1( or multiple 1's) then indicator=1 .
It means that there is "hole" of zero between one's. In real life it mean that customer was exist snd then disappeared and then exist again
yabwon
Onyx | Level 15

ok, so it looks like my code does what you need.

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Ronein
Meteorite | Level 14

Both codes provide same result which is perfect:)

Data have;
input X $ 20.;;
cards;
010101 
000001
000011
000111
001111
011111
111111
110011
110111
111001
100001
001001
001011
010011
101001
101101
000000000001
000000000101
000000000011
000001011111
100000000001
101010101011
;
Run;

data want1;
set have;
y=prxchange('s/0+/0/',-1,x);
z=prxchange('s/1+/1/',-1,y);
Indicator1=ifn(find(z,'101'),1,0);
drop y z;
run;

data want2;
set have;
Indicator2 =  mod(X,2) /* not ends with 0 */ * (countw(X,"0","B") > 1) /* has at least 2 sequences of 1s (counting from right) */;
run;

proc sql;
create table compare_results(Where=(Indicator1 ne Indicator2)) as
select a.*,b.Indicator2
from want1  as a
left join want2 as b
on a.X=b.X
;
quit;
 
yabwon
Onyx | Level 15

You didn't read what I wrote in my answer about "if zeros at the end are not important"...

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Ronein
Meteorite | Level 14

Actually cannot have zero at end because the check is for customers that exist today (value 1)

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
  • 18 replies
  • 1920 views
  • 8 likes
  • 4 in conversation