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;
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
  • 2172 views
  • 12 likes
  • 7 in conversation