BookmarkSubscribeRSS Feed
infoneimanhpi
Calcite | Level 5

Hello,

I have data where I have an indicator for when someone had coverage in a year. I need to add across a row starting at the first 1 a person has and stopping when there is a '.'.  The 1 can start not at the first year and can have 1's after the streak ends. 

 

This is what it looks like now:

IDYr_2000Yr_2001Yr_2002Yr_2003Yr_2004Yr_2005Yr_2006Yr_2007Yr_2008Yr_2009Yr_2010
A111...11...
B...111....1
C...........
D.11111111..
E...........
F11.1..11...
G.....1111.1
H..........1
ID.111.......
G1.......1..
K11111.....

.

 

I want a table like this:

IDCoverage Length
A3
B3
C0
D8
E0
F2
G4
H1
ID3
G1
K5

 

Thank you!

7 REPLIES 7
PaigeMiller
Diamond | Level 26

UNTESTED CODE

 

data want;
    set have;
    array yr(*) yr_2000-yr_2010;
    count=0;
    do i=1 to dim(yr);
        count=sum(count,yr(i));
        if count>0 and missing(yr(i)) then leave;
    end;
run;

If you want tested code, you need to provide the data as SAS data step code and not as a screen capture.

--
Paige Miller
Ksharp
Super User
data have;
infile cards expandtabs truncover;
input ID $ Yr_2000 Yr_2001 Yr_2002 Yr_2003 Yr_2004 Yr_2005 Yr_2006 Yr_2007 Yr_2008 Yr_2009 Yr_2010 ;
cards;
A   1   1   1   .   .   .   1   1   .   .   .
B   .   .   .   1   1   1   .   .   .   .   1
C   .   .   .   .   .   .   .   .   .   .   .
D   .   1   1   1   1   1   1   1   1   .   .
E   .   .   .   .   .   .   .   .   .   .   .
F   1   1   .   1   .   .   1   1   .   .   .
G   .   .   .   .   .   1   1   1   1   .   1
H   .   .   .   .   .   .   .   .   .   .   1
ID  .   1   1   1   .   .   .   .   .   .   .
G   1   .   .   .   .   .   .   .   1   .   .
K   1   1   1   1   1   .   .   .   .   .   .
;

data want;
 set have;
 temp=cats(of Yr_:);
 pid=prxparse('/1+/o');
 s=1;e=length(temp); cover_len=0;
 call prxnext(pid,s,e,temp,p,l);
 do while(p>0);
   cover_len=max(cover_len,l);
   call prxnext(pid,s,e,temp,p,l);
 end;
 drop s e p l temp;
run;
novinosrin
Tourmaline | Level 20

data have;
input ID $	Yr_2000	Yr_2001	Yr_2002	Yr_2003	Yr_2004	Yr_2005	Yr_2006	Yr_2007	Yr_2008	Yr_2009	Yr_2010;
cards;
A	1	1	1	.	.	.	1	1	.	.	.
B	.	.	.	1	1	1	.	.	.	.	1
C	.	.	.	.	.	.	.	.	.	.	.
D	.	1	1	1	1	1	1	1	1	.	.
E	.	.	.	.	.	.	.	.	.	.	.
F	1	1	.	1	.	.	1	1	.	.	.
G	.	.	.	.	.	1	1	1	1	.	1
H	.	.	.	.	.	.	.	.	.	.	1
ID	.	1	1	1	.	.	.	.	.	.	.
G	1	.	.	.	.	.	.	.	1	.	.
K	1	1	1	1	1	.	.	.	.   .   .
;


data want;
 set have;
 array t Yr_2000--	Yr_2010;
 junk1=cats(of t(*));
 junk2=index(junk1,'1');
 if junk2 then junk3=substr(junk1,junk2);
 junk4=verify(junk3,'1');
 junk5=coalesce(of t(*));
 cover_length=0;
 if junk5 then cover_length=junk4-junk5;
 drop junk: Yr_2000--	Yr_2010;
run;
FreelanceReinh
Jade | Level 19

Hello @infoneimanhpi,

 

Maybe it's as easy as this:

data want(keep=id c:);
set have;
Coverage_Length=lengthn(scan(cats(of Yr_2000-Yr_2010),1));
run;
LeonidBatkhan
Lapis Lazuli | Level 10

Hi infoneimanhpi,

You can do it as follows:

data HAVE;
   input ID $ Yr_2000-Yr_2010;
   datalines;
A   1   1   1   .   .   .   1   1   .   .   .
B   .   .   .   1   1   1   .   .   .   .   1
C   .   .   .   .   .   .   .   .   .   .   .
D   .   1   1   1   1   1   1   1   1   .   .
E   .   .   .   .   .   .   .   .   .   .   .
F   1   1   .   1   .   .   1   1   .   .   .
G   .   .   .   .   .   1   1   1   1   .   1
H   .   .   .   .   .   .   .   .   .   .   1
I   .   1   1   1   .   .   .   .   .   .   .
G   1   .   .   .   .   .   .   .   1   .   .
K   1   1   1   1   1   .   .   .   .   .   .
;

data WANT (keep=ID c);
   set HAVE;
   array y Yr_2000-Yr_2010;
   c = 0;
   do i=1 to dim(y) until(c>0 and y[i]=.);
      c = sum(c,y[i]);
   end;
   label c = 'Coverage Length';
run;

Hope this helps.

 

Ksharp
Super User

What if the max length is at last , not first ? Like :

A 1 1 1 . . . 1 1 1 1 1
B . . . 1 . . . . . 1 1

Patrick
Opal | Level 21

Below two options to get what you want.

data have;
infile cards expandtabs truncover;
input ID $ Yr_2000 Yr_2001 Yr_2002 Yr_2003 Yr_2004 
      Yr_2005 Yr_2006 Yr_2007 Yr_2008 Yr_2009 Yr_2010 ;
cards;
A   1   1   1   .   .   .   1   1   .   .   .
B   .   .   .   1   1   1   .   .   .   .   1
C   .   .   .   .   .   .   .   .   .   .   .
D   .   1   1   1   1   1   1   1   1   .   .
E   .   .   .   .   .   .   .   .   .   .   .
F   1   1   .   1   .   .   1   1   .   .   .
G   .   .   .   .   .   1   1   1   1   .   1
H   .   .   .   .   .   .   .   .   .   .   1
ID  .   1   1   1   .   .   .   .   .   .   .
G   1   .   .   .   .   .   .   .   1   .   .
K   1   1   1   1   1   .   .   .   .   .   .
;


data want1(drop=_: yr_:);
  set have;
  _str=catt(of yr_:);
  max_len=0;
  _stop=countw(_str,'.');
  do _i=1 to _stop;
    max_len=max(max_len,lengthn(scan(_str,_i,'.')));
  end;
run;
proc print data=want1;
run;

data want2(drop=_: yr_:);
  set have;
  array yrs {*} yr_:;
  do _i=1 to dim(yrs);
    _len= sum(0,_len,yrs[_i]) * (yrs[_i]=1);
    max_len=max(_len,max_len);
  end;
run;
proc print data=want2;
run;

Patrick_0-1595132803501.png

 

sas-innovate-wordmark-2025-midnight.png

Register Today!

Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.


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
  • 7 replies
  • 1266 views
  • 7 likes
  • 7 in conversation