Hi,
I am trying to transform how my data is laid out. The data that I am starting with is formatted as such:
Product | Metric | Actual | Forecast | Total |
A | Sales | 10 | 10 | 20 |
A | Profit | 5 | 5 | 10 |
B | Sales | 20 | 20 | 40 |
B | Profit | 15 | 15 | 30 |
I am trying to transform my data to look like this:
Product | Sales Actual | Sales Forecast | Sales Total | Profit Actual | Profit Forecast | Profit Total |
A | 10 | 10 | 20 | 5 | 5 | 10 |
B | 20 | 20 | 40 | 15 | 15 | 30 |
I am newer to SAS, but have had success with transposing data in the past though i have not been able to get it to work with this dataset.
Thank you in advance for the help,
Emily
Here's one way:
data want;
merge have (where=(metric='Sales') rename=(actual=Sales_Actual forecast=Sales_Forecast total=Sales_Total))
have (where=(metric='Profit') rename=(actual=Profit_Actual forecast=Profit_Forecast total=Profit_Total));
by product;
drop metric;
run;
It assumes your data set is already sorted by PRODUCT.
Here's one way:
data want;
merge have (where=(metric='Sales') rename=(actual=Sales_Actual forecast=Sales_Forecast total=Sales_Total))
have (where=(metric='Profit') rename=(actual=Profit_Actual forecast=Profit_Forecast total=Profit_Total));
by product;
drop metric;
run;
It assumes your data set is already sorted by PRODUCT.
Thank you so much Astounding! This worked for me.
data have;
input Product $ Metric $ Actual Forecast Total;
cards;
A Sales 10 10 20
A Profit 5 5 10
B Sales 20 20 40
B Profit 15 15 30
;
proc transpose data=have out=_have;
by product metric notsorted;
var Actual Forecast Total;
run;
proc transpose data=_have out=want;
by product;
var col1;
id metric _name_;
run;
I don't think astounding solution is a proper automated solution. In my opinion that's hard coding and will not scale if the number of metric changes.
OK. Merge Skill come to rescue. proposed by me,Matt,Arthur.T:
http://support.sas.com/resources/papers/proceedings15/2785-2015.pdf
data have;
input Product $ Metric $ Actual Forecast Total;
cards;
A Sales 10 10 20
A Profit 5 5 10
B Sales 20 20 40
B Profit 15 15 30
;
proc sort data=have(keep=Metric) out=key nodupkey;
by Metric;
run;
data _null_;
set key end=last;
if _n_=1 then call execute('data want;merge ');
call execute(catt('have(where=(Metric="',Metric,'")
rename=(Actual=',Metric,'_Actual Forecast=',Metric,'_Forecast Total=',Metric,'_Total))'));
if last then call execute(';by Product;drop Metric;run;');
run;
OK. Merge Skill come to rescue. proposed by me,Matt,Arthur.T:
http://support.sas.com/resources/papers/proceedings15/2785-2015.pdf
data have;
input Product $ Metric $ Actual Forecast Total;
cards;
A Sales 10 10 20
A Profit 5 5 10
B Sales 20 20 40
B Profit 15 15 30
;
proc sort data=have(keep=Metric) out=key nodupkey;
by Metric;
run;
data _null_;
set key end=last;
if _n_=1 then call execute('data want;merge ');
call execute(catt('have(where=(Metric="',Metric,'")
rename=(Actual=',Metric,'_Actual Forecast=',Metric,'_Forecast Total=',Metric,'_Total))'));
if last then call execute(';by Product;drop Metric;run;');
run;
Do you mind walking me through what you are doing here? I'm not sure I am following:
call execute(catt('have(where=(Metric="',Metric,'")
rename=(Actual=',Metric,'_Actual Forecast=',Metric,'_Forecast Total=',Metric,'_Total))'));
if last then call execute(';by Product;drop Metric;run;')
This produce the Astounding's code . data want; merge have (where=(metric='Sales') rename=(actual=Sales_Actual forecast=Sales_Forecast total=Sales_Total)) have (where=(metric='Profit') rename=(actual=Profit_Actual forecast=Profit_Forecast total=Profit_Total)); by product; drop metric; run;
Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!
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.
Ready to level-up your skills? Choose your own adventure.