<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Count number of value 1 using do loop in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902224#M356525</link>
    <description>&lt;P&gt;Because your variable Value contains 1, -1 or missing you could simply use this variable for the count. In the code I proposed already change...&lt;/P&gt;
&lt;PRE&gt;from:
count=sum(count,1)

to:
count=sum(count,_firstNonMiss)&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here the amended code:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want(drop=_:);
  set have;
  do _i=_n_ to _n_+5 while(_i&amp;lt;=_nobs);
    set have(keep=id value rename=(id=_id value=_value)) nobs=_nobs point=_i;
    if id ne _id then leave;

    _firstNonMiss = coalesce(_firstNonMiss,_value);
    if n(_firstNonMiss, _value)=2 then
      do;
        if _firstNonMiss=_value then count=sum(count,_firstNonMiss);
        else leave;
      end;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;If in your real data the value could also be something else than 1, -1 or missing and you just want a count until the value changes then below expression should work:&lt;/P&gt;
&lt;PRE&gt;count=sum(count, abs(_firstNonMiss)/_firstNonMiss );&lt;/PRE&gt;</description>
    <pubDate>Thu, 09 Nov 2023 01:21:06 GMT</pubDate>
    <dc:creator>Patrick</dc:creator>
    <dc:date>2023-11-09T01:21:06Z</dc:date>
    <item>
      <title>Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902008#M356424</link>
      <description>&lt;P&gt;Hi Everyone,&lt;/P&gt;
&lt;P&gt;My data has id and value.&lt;/P&gt;
&lt;P&gt;For each row[i], I want to check the window from [i] to [i+5]. I want to find the first non-missing value, say 1, and count how many 1 before -1 shows up.&lt;/P&gt;
&lt;P&gt;If the first non-missing value is -1, I want to count how many -1 before 1 show up.&lt;/P&gt;
&lt;P&gt;To distinguish between 1 series and -1 series, the count should have + sign for 1 and - sign for -1.&lt;/P&gt;
&lt;P&gt;In my data below, the first row is 1, which serves as the first non-missing, thus the count is 3 (value 1)&lt;/P&gt;
&lt;P&gt;2nd row: count = 2&lt;/P&gt;
&lt;P&gt;3 row: count=1&lt;/P&gt;
&lt;P&gt;4 row: count =1 as -1 shows in 7the record&amp;nbsp;&lt;/P&gt;
&lt;P&gt;My code is below and I really curious why it doesn't work.&lt;/P&gt;
&lt;P&gt;It appears that the count is wrong for row with value =. and for the last few rows.&lt;/P&gt;
&lt;P&gt;For simplicity, I don't introduce the condition of the same id yet.&lt;/P&gt;
&lt;P&gt;Can you please help?&lt;/P&gt;
&lt;P&gt;Many thanks,&lt;/P&gt;
&lt;P&gt;HHC&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have; 
input id value;
datalines;
1 1
1 .
1 1
1 .
1 1
1 .
1 -1
1 1
1 .
2 1
2 1
2 .
;run;

data want; 
set have nobs=nobs;
drop i j_: out_:;
i+1;
out_j=0;
count=0;

DO j=i to i+5 until (j=nobs or out_j=1);
out_k=0;
set have (keep = id value rename=(id=j_id value=j_value)) point=j;

	IF j_value&amp;gt;0  then do; /*checking positive value*/
		do k=j to i+5  until (k=nobs or out_k=1);
		set have (keep = id value rename=(id=k_id value=k_value)) point=k;
			if k_value&amp;gt;0 then
				count=count+1;
			else 
			if k_value =-1 then do;
				out_k=1;
				leave;
				end;

		END;
		End;

	ELSE
	IF j_value&amp;lt;0  then do;/*checking positive value*/
		do k=j to i+5  until (k=nobs or out_k=1);
		set have (keep = id value rename=(id=k_id value=k_value)) point=k;
			if k_value&amp;lt;0 and k_value^=. then
				count=count-1;
			else 
			if k_value =1 then do;
				out_k=1;
				leave;
				end;

		END;
		End;
	
	if out_k=1 then out_j=1;

END;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 08 Nov 2023 12:56:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902008#M356424</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2023-11-08T12:56:48Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902012#M356427</link>
      <description>&lt;P&gt;I didn't spend enough time on your code to answer your question but check if below a bit simpler version returns the desired result.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  input id value;
  datalines;
1 1
1 .
1 1
1 .
1 1
1 .
1 -1
1 1
1 .
2 1
2 1
2 .
;

data want(drop=_:);
  set have;
  do _i=_n_ to _n_+5 while(_i&amp;lt;=_nobs);
    set have(keep=id value rename=(id=_id value=_value)) nobs=_nobs point=_i;
    if id ne _id then leave;

    _firstNonMiss = coalesce(_firstNonMiss,_value);
    if n(_firstNonMiss, _value)=2 then
      do;
        if _firstNonMiss=_value then count=sum(count,1);
        else leave;
      end;
  end;
run;

proc print data=want;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 08 Nov 2023 09:18:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902012#M356427</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2023-11-08T09:18:04Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902014#M356429</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*
Since your data process logic is so complicated,
I would like to use ARRAY.*/
data have; 
input id value;
datalines;
1 1
1 .
1 1
1 .
1 1
1 .
1 -1
1 1
1 .
2 1
2 1
2 .
3 1
3 1
3 .
3 -1
3 -1
3 .
3 -1
3 1
3 -1
;

data want;
array x{9999} _temporary_;
call missing(of x{*});

do j=1 by 1 until(last.id);
 set have;
 by id;
 x{j}=value;
end;

do i=1 by 1 until(last.id);
 set have;
 by id;
 found=0;count=0;first_no_missing=0;
 do k=i to i+5;
   if x{k} and not found then do;found=1;first_no_missing=x{k}; end;
   if x{k}=first_no_missing then count+1;
   if x{k}=-first_no_missing then leave;
 end;
 output;
end;
keep id value count;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 08 Nov 2023 09:46:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902014#M356429</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2023-11-08T09:46:20Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902022#M356435</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I'd follow an other approach. Rather than try to loop and perform the check within the next rows, I'd transpose the next rows and work with it.&lt;/P&gt;
&lt;P&gt;It eases debugging and code review (in my view)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I'm working id by id that is I won't compare the next rows if the id differs. I think it makes sense.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;That's what I come up with, let me know it suits your needs:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have; 
input id value;
datalines;
1 1
1 .
1 1
1 .
1 1
1 .
1 -1
1 1
1 .
2 1
2 1
2 .
;run;

data have1; 
set have;
i+1;
run;

*Macro to transpose the next rows;
%MACRO getnextRows(idvalue=1, i_position=1);
   DATA _tmp1;
      SET have1(where=(id=&amp;amp;idvalue. and &amp;amp;i_position.&amp;lt;=i&amp;lt;=&amp;amp;i_position.+5));
      i=&amp;amp;i_position.; *set i to &amp;amp;i_position. for merging after transpose;
      keep id value i;
   RUN;

   PROC TRANSPOSE DATA=_tmp1 out=_tmp2 prefix=next;
      BY id i;
      VAR value;
   RUN;

   DATA have1;
      MERGE have1 _tmp2;
      BY id i;
   RUN;

   PROC DATASETS lib=work nolist; delete _tmp:; RUN;QUIT;
%MEND getnextRows;

%MACRO reset(vars,val);
   array _vars_ &amp;amp;vars.;
   do over _vars_;
      _vars_=&amp;amp;val.;
   end;
%MEND reset;

*Create working dataset with transposed rows;
DATA _NULL_;
   set have1;
   call execute('%nrstr(%getnextRows(idvalue='||strip(put(id,best.))||', i_position='||strip(put(i,best.))||'))');
RUN;

DATA want;
   SET have1;
   ARRAY nextRow(6) NEXT1-NEXT6; *NEXT1 is actually the current row;
   %reset(count countPos countNeg firstValue,0);
   DO c1=1 TO 6;
      *Check for first non-missing value and get position of firstValue or -firstValue;
      if sum(count, countPos, countNeg)=0 then do;
         firstValue=nextRow[c1];
         if not missing(firstValue) then do;
            count+1;
            if firstValue&amp;gt;0  then countPos+1;
            else if .&amp;lt;firstValue&amp;lt;0 then countNeg+1;
         end;
      end;
      else do;
         *count how many firstValue until -firstValue;
         if nextRow[c1]=-firstValue then leave;
         else if nextRow[c1]=firstValue then do;
            count+1;
            if firstValue&amp;gt;0 then countPos+1;
            else countNeg+1;
         end;
      end;
   END;
   keep id value count:;
RUN;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 08 Nov 2023 11:52:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902022#M356435</guid>
      <dc:creator>Oligolas</dc:creator>
      <dc:date>2023-11-08T11:52:12Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902030#M356440</link>
      <description>&lt;P&gt;That's the best piece of code I've ever seen&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 08 Nov 2023 11:14:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902030#M356440</guid>
      <dc:creator>Oligolas</dc:creator>
      <dc:date>2023-11-08T11:14:40Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902032#M356441</link>
      <description>&lt;P&gt;Hi Everyone,&lt;/P&gt;
&lt;P&gt;Thank you so much for helping.&lt;/P&gt;
&lt;P&gt;The issue is that, I have been using this Do Loop as my tool and failing it this time make me very uncomfortable and unconfident about my code.&lt;/P&gt;
&lt;P&gt;I see the logic is quite straight forward to implement &lt;span class="lia-unicode-emoji" title=":confused_face:"&gt;😕&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;I hope you guys expert can help me to fix my code.&lt;/P&gt;
&lt;P&gt;Thanks,&lt;/P&gt;
&lt;P&gt;HHC&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 08 Nov 2023 11:56:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902032#M356441</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2023-11-08T11:56:57Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902038#M356444</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/18408"&gt;@Ksharp&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/12447"&gt;@Patrick&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For negative series, I need the count having - sign. Otherwise, there is no distinguish between +1 series vs. -1 series.&lt;/P&gt;
&lt;P&gt;Can you help?&lt;/P&gt;
&lt;P&gt;Thanks,&lt;/P&gt;
&lt;P&gt;HHC&lt;/P&gt;</description>
      <pubDate>Wed, 08 Nov 2023 13:01:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902038#M356444</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2023-11-08T13:01:26Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902224#M356525</link>
      <description>&lt;P&gt;Because your variable Value contains 1, -1 or missing you could simply use this variable for the count. In the code I proposed already change...&lt;/P&gt;
&lt;PRE&gt;from:
count=sum(count,1)

to:
count=sum(count,_firstNonMiss)&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here the amended code:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want(drop=_:);
  set have;
  do _i=_n_ to _n_+5 while(_i&amp;lt;=_nobs);
    set have(keep=id value rename=(id=_id value=_value)) nobs=_nobs point=_i;
    if id ne _id then leave;

    _firstNonMiss = coalesce(_firstNonMiss,_value);
    if n(_firstNonMiss, _value)=2 then
      do;
        if _firstNonMiss=_value then count=sum(count,_firstNonMiss);
        else leave;
      end;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;If in your real data the value could also be something else than 1, -1 or missing and you just want a count until the value changes then below expression should work:&lt;/P&gt;
&lt;PRE&gt;count=sum(count, abs(_firstNonMiss)/_firstNonMiss );&lt;/PRE&gt;</description>
      <pubDate>Thu, 09 Nov 2023 01:21:06 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902224#M356525</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2023-11-09T01:21:06Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902225#M356526</link>
      <description>&lt;P&gt;You'd better some real data you have and the output you want to see to illustrate your question better.&lt;/P&gt;
&lt;P&gt;If you want count POSITIVE or NEGATIVE number , try this one :&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*
Since your data process logic is so complicated,
I would like to use ARRAY.*/
data have; 
input id value;
datalines;
1 11
1 .
1 12
1 .
1 11
1 .
1 -12
1 11
1 .
2 12
2 13
2 .
3 14
3 15
3 .
3 -11
3 -12
3 .
3 -13
3 11
3 -14
;

data want;
array x{9999} _temporary_;
call missing(of x{*});

do j=1 by 1 until(last.id);
 set have;
 by id;
 x{j}=value;
end;

do i=1 by 1 until(last.id);
 set have;
 by id;
 found=0;count=0;first_no_missing=0;
 do k=i to i+5;
   if x{k} and not found then do;found=1;first_no_missing=x{k}; end;
   if sign(x{k})=sign(first_no_missing) then count+1;
   if sign(x{k})=-sign(first_no_missing) then leave;
 end;
 output;
end;
keep id value count;
run;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 09 Nov 2023 01:05:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902225#M356526</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2023-11-09T01:05:01Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902262#M356544</link>
      <description>&lt;P&gt;You can do a self-merge of obs i through obs i+5.&amp;nbsp; Put the values of ID and VALUE in arrays.&amp;nbsp; Then use those arrays to generate COUNT.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I understand that if the reference value is -1, then you want to count negative ones, and also give a negative sign to COUNT, so the below uses the SIGN function.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Because there is an array for ID's as well as for VALUE's, it's easy to avoid examining obs for the upcoming ID.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have; 
input id value @@;
datalines;
1  1    1  .    1  1    1  .    1  1    
1  .    1 -1    1  1    1  .    
2  1    2  1    2  .    
run;

data want (drop=_: i);
  merge have (firstobs=1)
        have (firstobs=2 keep=id value rename=(id=_id2 value=_val2))
        have (firstobs=3 keep=id value rename=(id=_id3 value=_val3))
        have (firstobs=4 keep=id value rename=(id=_id4 value=_val4))
        have (firstobs=5 keep=id value rename=(id=_id5 value=_val5))
        have (firstobs=6 keep=id value rename=(id=_id6 value=_val6)) ;

  array _x {*} id     _id:  ;
  array _v {*} value  _val: ;

  count=0;
  do i=1 to dim(_x) while(id=_x{i});
    if _nonmiss1=. then _nonmiss1=_v{i};
    else if _v{i}=. then continue;
    else if _v{i}=_nonmiss1 then count=count+sign(_nonmiss1);
    else if sign(_v{i})=-1*sign(_nonmiss1) then leave;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 09 Nov 2023 04:45:59 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902262#M356544</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2023-11-09T04:45:59Z</dc:date>
    </item>
    <item>
      <title>Re: Count number of value 1 using do loop</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902265#M356547</link>
      <description>&lt;P&gt;Thank you, Ksharp for helping.&lt;/P&gt;
&lt;P&gt;HHC&lt;/P&gt;</description>
      <pubDate>Thu, 09 Nov 2023 05:20:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Count-number-of-value-1-using-do-loop/m-p/902265#M356547</guid>
      <dc:creator>hhchenfx</dc:creator>
      <dc:date>2023-11-09T05:20:14Z</dc:date>
    </item>
  </channel>
</rss>

