BookmarkSubscribeRSS Feed
PITERSON_X_TB
Calcite | Level 5

I want to sum 1s for a given key, but only the last ones, if there was a gap, i.e. there was 0, I do not want to sum. example below:

 

IDval_202001val_202002val_202003val_202004val_202005val_202006val_202007val_202008val_202009val_202010val_202011val_202012val_202101val_202102val_202103 expected
1111111111111111 15
2110011111111111 11
3000000000011111 5

 

Thanks for your help / inspiration

Qb-eg
8 REPLIES 8
PaigeMiller
Diamond | Level 26

UNTESTED CODE

 

data want;
    set have;
    array x val_202001--val_202103;
    expected=0;
    do i=dim(x) to 1 by -1;
         if x(i)=1 then expected=expected+1;
         else if x(i)=0 then leave;
    end;
    drop i;
run;

 

If you want tested code, please provide (a portion of) the data as SAS data step code, which you can type in yourself, or create it via these instructions.

--
Paige Miller
Kurt_Bremser
Super User

Do not keep data in structure, it makes working with it more complicated.

So first, transpose:

proc transpose data=have out=long (rename=(_name_=period col1=value));
by id;
var val:;
run;

Then it is easy:

data want;
set long;
by id;
if first.id or value = 0
then expected = 0;
else expected + 1;
if last.id;
run;
novinosrin
Tourmaline | Level 20

data have;
input ID	val_202001	val_202002	val_202003	val_202004	val_202005	val_202006	val_202007	val_202008	val_202009	val_202010	val_202011	val_202012	val_202101	val_202102	val_202103 ;
cards;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1
2	1	1	0	0	1	1	1	1	1	1	1	1	1	1	1
3	0	0	0	0	0	0	0	0	0	0	1	1	1	1	1
;

data want;
  set have;
  array t(*) val_: ;
  want = dim(t) - findc(cats(of t(*)),'0','b');
run;
average_joe
Obsidian | Level 7
Not nearly as intuitive as the previous solutions, but very pithy.
novinosrin
Tourmaline | Level 20

Thank you @average_joe 

Astounding
PROC Star

Could your series end with 0?  Could there be multiple groups, not just 1 or 2?  What should the result look like for these series of values?

1	1	0	0	1	1	1	1	1	1	1	1	1	0	1
1	1	0	0	1	1	1	1	1	1	1	1	1	0	0
novinosrin
Tourmaline | Level 20

 Sir @Astounding  Nice one. Indeed a certain possibility that expects the logic to pick just the right most set of 1's if it were to exist -


data have;
input ID	val_202001	val_202002	val_202003	val_202004	val_202005	val_202006	val_202007	val_202008	val_202009	val_202010	val_202011	val_202012	val_202101	val_202102	val_202103 ;
cards;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1
2	1	1	0	0	1	1	1	1	1	1	1	1	1	1	1
3	0	0	0	0	0	0	0	0	0	0	1	1	1	1	1
4   1	1	0	0	1	1	1	1	1	1	1	1	1	0	1
5   1	1	0	0	1	1	1	1	1	1	1	1	1	0	0
6   0	0	0	0	0 	0 	0	0	0	0	0	0	0	0	0
;

data want;
  set have;
  array t(*) val_: ;
  want = lengthn(scan(cats(of t(*)),-1,'1','k'));
run;

 

Ksharp
Super User
data have;
input ID	val_202001	val_202002	val_202003	val_202004	val_202005	val_202006	val_202007	val_202008	val_202009	val_202010	val_202011	val_202012	val_202101	val_202102	val_202103 ;
cards;
1	1	1	1	1	1	1	1	1	1	1	1	1	1	1	1
2	1	1	0	0	1	1	1	1	1	1	1	1	1	1	1
3	0	0	0	0	0	0	0	0	0	0	1	1	1	1	1
4   1	1	0	0	1	1	1	1	1	1	1	1	1	0	1
5   1	1	0	0	1	1	1	1	1	1	1	1	1	0	0
6   0	0	0	0	0 	0 	0	0	0	0	0	0	0	0	0
;

data want;
  set have;
temp=cats(of val_:);
pid=prxparse('/1+/');
s=1;e=length(temp);
call prxnext(pid,s,e,temp,p,l);
do while(p>0);
 want=l;
 call prxnext(pid,s,e,temp,p,l);
end;
drop temp pid s e p l;
run;

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 8 replies
  • 1182 views
  • 12 likes
  • 7 in conversation