From: Muthia Kachirayan on
I was late to read this thread. Mike Zdeb has given a solution based on proc
summary and proc rank. I was thinking to use hash objects. It looked
difficult at first to incorporate all the needs of the OP in a hash
solution. It is not.


data have;
input state : $2. sumval color : $6.;
datalines;
AK 10 Red
AK 12 Blue
AK 7 Green
AZ 3 Yellow
AZ 5 Red
AZ 20 Blue
NY 2 Green
;
run;

It needs a presorted data set to get the ranks. A hash table is stored
based on the keys of color and state. Another hash table is built to save
only the unique colors to check the presence in the former hash table to add
missing values.


proc sort data = have;
by color descending sumval;
run;

data _null_;
if _n_ = 1 then do;
if 0 then set have;

declare hash h(ordered:'y');
h.definekey('color','state');
h.definedata('color','state','sumval','rank');
h.definedone();

declare hash s(ordered:'y');
s.definekey('st');
s.definedone();

do until(z);
do until(last.color);
set have(keep = state rename=(state = st)) end = z;
if s.check() ne 0 then s.add();
end;
end;

declare hiter hi('s');
end;

do until(last);
rank = 0;
do until(last.color);
set have end = last;
by color;
if h.find() ne 0 then rank + 1;
h.replace();
end;

** check all states are inserted;

do rc = hi.first() by 0 while(rc = 0);
if h.find(key:color,key:st) ne 0 then do;
state = st;
sumval = 0;
rank = .;
h.add();
end;
rc = hi.next();
end;
end;
h.output(dataset:'need');
stop;
run;

proc print data = need noobs;
run;

The output of dataset:


color state sumval rank

Blue AK 12 2
Blue AZ 20 1
Blue NY 0 .
Green AK 7 1
Green AZ 0 .
Green NY 2 2
Red AK 10 1
Red AZ 5 2
Red NY 0 .
Yellow AK 0 .
Yellow AZ 3 1
Yellow NY 0 .


Muthia Kachirayan

On Tue, Mar 2, 2010 at 7:14 PM, Sdlentertd <sdlentertd(a)gmail.com> wrote:

> I need help figuring out how to rank my results by state.For each
> color what is the rank(based on SumVal) for all states .. I have this
> SAS dataset
>
> State sumval Color
> AK 10 Red
> AK 12 Blue
> AK 7 Green
> AZ 3 Yellow
> AZ 5 Red
> AZ 20 Blue
> NY 2 Green
>
> etc...
> The output will list all states with Rankings by Color :
>
> Red
> State SumVal Rank
> AK 10 1
> AZ 5 2
> NY 0 .
>
> Blue
> State SumVal Rank
> AK 12 2
> AZ 20 1
> NY 0 .
>
> Green
> State SumVal Rank
> AK 0 .
> AZ 3 1
> NY 0 .
>
> Green
> State SumVal Rank
> AK 7 1
> AZ 0 .
> NY 2 2
>
> So one report for each of Colors (I have 50 or so)
> and I need to list all 50 states even if the value is 0, and if the
> value is zero that the rank should be missing.
> Thank you
>
From: Muthia Kachirayan on
It is not unique colors but state.

On Thu, Mar 4, 2010 at 12:40 PM, Muthia Kachirayan <
muthia.kachirayan(a)gmail.com> wrote:

> I was late to read this thread. Mike Zdeb has given a solution based on
> proc summary and proc rank. I was thinking to use hash objects. It looked
> difficult at first to incorporate all the needs of the OP in a hash
> solution. It is not.
>
>
> data have;
>
> input state : $2. sumval color : $6.;
> datalines;
> AK 10 Red
> AK 12 Blue
> AK 7 Green
> AZ 3 Yellow
> AZ 5 Red
> AZ 20 Blue
> NY 2 Green
> ;
> run;
>
> It needs a presorted data set to get the ranks. A hash table is stored
> based on the keys of color and state. Another hash table is built to save
> only the unique colors to check the presence in the former hash table to add
> missing values.
>
>
> proc sort data = have;
> by color descending sumval;
> run;
>
> data _null_;
> if _n_ = 1 then do;
>
> if 0 then set have;
>
> declare hash h(ordered:'y');
> h.definekey('color','state');
> h.definedata('color','state','sumval','rank');
> h.definedone();
>
> declare hash s(ordered:'y');
> s.definekey('st');
> s.definedone();
>
> do until(z);
> do until(last.color);
> set have(keep = state rename=(state = st)) end = z;
> if s.check() ne 0 then s.add();
> end;
> end;
>
> declare hiter hi('s');
> end;
>
> do until(last);
> rank = 0;
> do until(last.color);
> set have end = last;
> by color;
> if h.find() ne 0 then rank + 1;
> h.replace();
> end;
>
> ** check all states are inserted;
>
> do rc = hi.first() by 0 while(rc = 0);
> if h.find(key:color,key:st) ne 0 then do;
> state = st;
> sumval = 0;
> rank = .;
> h.add();
> end;
> rc = hi.next();
> end;
> end;
> h.output(dataset:'need');
> stop;
> run;
>
> proc print data = need noobs;
> run;
>
> The output of dataset:
>
>
> color state sumval rank
>
> Blue AK 12 2
> Blue AZ 20 1
> Blue NY 0 .
> Green AK 7 1
> Green AZ 0 .
> Green NY 2 2
> Red AK 10 1
> Red AZ 5 2
> Red NY 0 .
> Yellow AK 0 .
> Yellow AZ 3 1
> Yellow NY 0 .
>
>
> Muthia Kachirayan
>
> On Tue, Mar 2, 2010 at 7:14 PM, Sdlentertd <sdlentertd(a)gmail.com> wrote:
>
>> I need help figuring out how to rank my results by state.For each
>> color what is the rank(based on SumVal) for all states .. I have this
>> SAS dataset
>>
>> State sumval Color
>> AK 10 Red
>> AK 12 Blue
>> AK 7 Green
>> AZ 3 Yellow
>> AZ 5 Red
>> AZ 20 Blue
>> NY 2 Green
>>
>> etc...
>> The output will list all states with Rankings by Color :
>>
>> Red
>> State SumVal Rank
>> AK 10 1
>> AZ 5 2
>> NY 0 .
>>
>> Blue
>> State SumVal Rank
>> AK 12 2
>> AZ 20 1
>> NY 0 .
>>
>> Green
>> State SumVal Rank
>> AK 0 .
>> AZ 3 1
>> NY 0 .
>>
>> Green
>> State SumVal Rank
>> AK 7 1
>> AZ 0 .
>> NY 2 2
>>
>> So one report for each of Colors (I have 50 or so)
>> and I need to list all 50 states even if the value is 0, and if the
>> value is zero that the rank should be missing.
>> Thank you
>>
>
>