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-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 18 replies
  • 774 views
  • 8 likes
  • 4 in conversation