- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hello everyone,
I try to get maximum value of rows with its maximum value column. I mean that I also see the Variable which is belong the Maximum value. I have a sample data set as below, also I have desired output as below. Can somebody help me, please?
Data Have;
Length CustomerID 8 Value1 8 Value2 8 Value3 8;
Infile Datalines MISSOVER;
Input CustomerID Value1 Value2 Value3 ;
DATALINES;
1 5 10 15
2 3 8 9
3 4 9 2
4 1 12 9
5 12 8 7
6 15 7 4
7 2 8 19
8 18 32 5
9 8 9 7
10 7 12 8
;
Run;
PROC SQL;
Create Table Want As
Select CustomerID,Value1,Value2,Value3,Max(Value1,Value2,Value3) As MaxValue
From Have
Having Max(Value1,Value2,Value3);
QUIT;
Desired output;
Thank you,
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
data want; set have; array v Value1 Value2 Value3; maxvalue = max(of v(*)); length maxvar $32.; maxvar = vname(v[whichn(maxvalue, of v(*))]); run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Your condition
Having Max(Value1,Value2,Value3)
is useless. The result of Max(Value1,Value2,Value3) is always > 0 and therefore a boolean true.
This is best done (IMO) in a data step with array processing:
data want;
set have;
array values {*} value1-value3;
maxval = 0;
maxind = 0;
do i = 1 to dim(values);
if values{i} > maxval
then do;
maxval = values{i};
maxind = i;
end;
end;
maxvalname = vname(values{maxind});
maxval = values(maxind);
keep customerid maxval maxvalname;
run;
It's a quick shot and might be optimizable, but it delivers the intended result.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi.
Here's another way, if that's OK for you to do it in two steps.
proc transpose data=HAVE out=HAVE2 (rename=(_NAME_=MaxValueOf COL1=MaxValue));
by CUSTOMERID;
var VALUE1 VALUE2 VALUE3;
run;
proc sql noprint;
create table WANT as
select a.CUSTOMERID, max(a.VALUE1, a.VALUE2, a.VALUE3) as MaxValue, b.MaxValueOf label=''
from HAVE as a, HAVE2 as b
where a.CUSTOMERID = b.CUSTOMERID and calculated MaxValue = b.MaxValue;
quit;
Fist step is to transpose data to create column MaxValueOf which holds the name of the value.
Second step will calculate max and match it against the named value.
Hope it helps.
Daniel Santos @ www.cgd.pt
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I would agree with @Kurt_Bremser that arrays are probably simplest, for instance if you have lots of "value"'s or don't know the number. For this specific instance however a simple case when can do the trick:
proc sql; create table WANT as select CUSTOMERID, max(VALUE1,VALUE2,VALUE3) as MAXVALUE, case when VALUE1=CALCULATED MAXVALUE then "Value1" when VALUE2=CALCULATED MAXVALUE then "Value2" when VALUE3=CALCULATED MAXVALUE then "Value3" else "" end as MAXVALUEOF from HAVE; quit;
Note that if multiple values have the max, then only the first will be the one given.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
data want; set have; array v Value1 Value2 Value3; maxvalue = max(of v(*)); length maxvar $32.; maxvar = vname(v[whichn(maxvalue, of v(*))]); run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I knew there would be something more elegant than just iterating through the array 😉
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
@Kurt_Bremser wrote:
I knew there would be something more elegant than just iterating through the array 😉
I have to thank @Reeza for showing me the whichn function in a post. That, and whichc, had snuck into to the SAS lexicon while I was working in an SPSS shop.