SAS "Double" 瀑布图
SAS "Double" Waterfall sgplot
我有一个如下所示的数据集:
data have;
input category $ type $ percent order;
datalines;
X Full 1 1
X B -.04 .
X A -.02 .
X E 0 .
X D .03 .
X C .01 .
;
run;
我想创建一个瀑布图,显示修改 A-E 后 "Leftover" 的内容。下面的代码成功地做到了这一点。
我有两个问题:
- 我希望从 "Leftover" 瀑布更进一步吧。假设另一个修改 F 的值为 0.60。我想从 "Leftover" 中减去这个值得到 "Leftover 2" (见图 http://tinypic.com/r/mb4tat/8 )。我不知道这是否可能,但我真的很想展示两个剩菜。
- 下面的代码很乱。我必须创建一些变通办法才能让条形图按我想要的顺序显示。有没有更好的方法来指定这些值?
谢谢!
proc sort data=have(where=(percent<0))
out=neg;
by percent;
run;
data neg;
set neg;
order=_N_+1;
run;
proc sql noprint;
select max(order) into :max_order from neg;
quit;
proc sort data=have(where=(percent>0 and type not in ("Full")))
out=pos;
by descending percent;
run;
data pos;
set pos;
order=_N_+&max_order.;
run;
data x_have;
set have(where=(type="Full")) neg pos;
run;
proc sort data=x_have;
by order;
run;
proc sgplot data=have(where=(percent ne 0)) noautolegend;
waterfall category=type response=percent / colorgroup=type dataskin=sheen datalabel name='a'
finalbartickvalue='Leftover';
;
xaxis display=(nolabel);
yaxis grid display=(nolabel) offsetmin=0;
run;
感谢@Joe 和 Sanjay Matange,我开始通过高低地块而不是瀑布图来解决这个问题。操作数据有点混乱,所以它是可重复的(我可能会回去清理一些),但这是任何感兴趣的人的解决方案。
data have;
input category $ type $ percent order;
datalines;
X Full 1 1
X B -.04 .
X A -.02 .
X E 0 .
X D .03 .
X C .01 .
X F .6 .
X sum1 . .
X sum2 . .
;
run;
proc sql noprint;
select sum(percent)
into :sum
from have
where type in ('A','B','C','D','E');
select percent
into :F
from have
where type='F';
select percent
into :maxperc
from have
where type="Full";
quit;
data have_mod;
set have;
if type='sum1' then percent=1+&sum.;
if type='sum2' then percent=1+&sum.-&F.;
run;
proc sort data=have_mod(where=(percent<0))
out=neg;
by percent;
run;
data neg;
set neg;
order=_N_+1;
run;
proc sql noprint;
select max(order) into :max_neg from neg;
quit;
proc sort data=have_mod(where=(percent>0 and type not in ("Full","sum1","sum2","F")))
out=pos;
by descending percent;
run;
data pos;
set pos;
order=_N_+&max_neg.;
run;
proc sql noprint;
select max(order) into :max_pos from pos;
quit;
data x_have;
set have_mod(where=(type in ("Full", "F", "sum1", "sum2"))) neg pos;
if type='sum1' then order=1+&max_pos.;
if type='F' then order=2+&max_pos.;
if type='sum2' then order=3+&max_pos.;
run;
proc sort data=x_have;
by order;
run;
proc sql noprint;
select percent, order
into :sum1, :ordersum1
from x_have
where type='sum1';
quit;
data want;
set x_have;
by category;
if first.category then sumpercent=0;
sumpercent+percent;
if type in ('sum1','F','sum2') then sumpercent=percent;
if type in ('Full','sum1','sum2') then high=sumpercent;
else if type='F' then high=&sum1.;
else if order=&ordersum1.-1 then high=&sum1.;
else if order=2 then high=&maxperc.;
else if percent>0 then high=sumpercent;
else if percent<0 then high=sumpercent+abs(percent);
if type in ('Full','sum1','sum2') then low=0;
else if percent<0 then low=sumpercent;
else if type='F' then low=high-sumpercent;
else if percent>0 then low=sumpercent-percent;
run;
proc sgplot data=want;
highlow x=type high=high low=low / group=type type=bar
groupdisplay=cluster highlabel=percent lineattrs=graphoutlines
dataskin=matte;
xaxis display=(nolabel noticks);
yaxis offsetmin=0;
run;
我有一个如下所示的数据集:
data have;
input category $ type $ percent order;
datalines;
X Full 1 1
X B -.04 .
X A -.02 .
X E 0 .
X D .03 .
X C .01 .
;
run;
我想创建一个瀑布图,显示修改 A-E 后 "Leftover" 的内容。下面的代码成功地做到了这一点。
我有两个问题:
- 我希望从 "Leftover" 瀑布更进一步吧。假设另一个修改 F 的值为 0.60。我想从 "Leftover" 中减去这个值得到 "Leftover 2" (见图 http://tinypic.com/r/mb4tat/8 )。我不知道这是否可能,但我真的很想展示两个剩菜。
- 下面的代码很乱。我必须创建一些变通办法才能让条形图按我想要的顺序显示。有没有更好的方法来指定这些值?
谢谢!
proc sort data=have(where=(percent<0))
out=neg;
by percent;
run;
data neg;
set neg;
order=_N_+1;
run;
proc sql noprint;
select max(order) into :max_order from neg;
quit;
proc sort data=have(where=(percent>0 and type not in ("Full")))
out=pos;
by descending percent;
run;
data pos;
set pos;
order=_N_+&max_order.;
run;
data x_have;
set have(where=(type="Full")) neg pos;
run;
proc sort data=x_have;
by order;
run;
proc sgplot data=have(where=(percent ne 0)) noautolegend;
waterfall category=type response=percent / colorgroup=type dataskin=sheen datalabel name='a'
finalbartickvalue='Leftover';
;
xaxis display=(nolabel);
yaxis grid display=(nolabel) offsetmin=0;
run;
感谢@Joe 和 Sanjay Matange,我开始通过高低地块而不是瀑布图来解决这个问题。操作数据有点混乱,所以它是可重复的(我可能会回去清理一些),但这是任何感兴趣的人的解决方案。
data have;
input category $ type $ percent order;
datalines;
X Full 1 1
X B -.04 .
X A -.02 .
X E 0 .
X D .03 .
X C .01 .
X F .6 .
X sum1 . .
X sum2 . .
;
run;
proc sql noprint;
select sum(percent)
into :sum
from have
where type in ('A','B','C','D','E');
select percent
into :F
from have
where type='F';
select percent
into :maxperc
from have
where type="Full";
quit;
data have_mod;
set have;
if type='sum1' then percent=1+&sum.;
if type='sum2' then percent=1+&sum.-&F.;
run;
proc sort data=have_mod(where=(percent<0))
out=neg;
by percent;
run;
data neg;
set neg;
order=_N_+1;
run;
proc sql noprint;
select max(order) into :max_neg from neg;
quit;
proc sort data=have_mod(where=(percent>0 and type not in ("Full","sum1","sum2","F")))
out=pos;
by descending percent;
run;
data pos;
set pos;
order=_N_+&max_neg.;
run;
proc sql noprint;
select max(order) into :max_pos from pos;
quit;
data x_have;
set have_mod(where=(type in ("Full", "F", "sum1", "sum2"))) neg pos;
if type='sum1' then order=1+&max_pos.;
if type='F' then order=2+&max_pos.;
if type='sum2' then order=3+&max_pos.;
run;
proc sort data=x_have;
by order;
run;
proc sql noprint;
select percent, order
into :sum1, :ordersum1
from x_have
where type='sum1';
quit;
data want;
set x_have;
by category;
if first.category then sumpercent=0;
sumpercent+percent;
if type in ('sum1','F','sum2') then sumpercent=percent;
if type in ('Full','sum1','sum2') then high=sumpercent;
else if type='F' then high=&sum1.;
else if order=&ordersum1.-1 then high=&sum1.;
else if order=2 then high=&maxperc.;
else if percent>0 then high=sumpercent;
else if percent<0 then high=sumpercent+abs(percent);
if type in ('Full','sum1','sum2') then low=0;
else if percent<0 then low=sumpercent;
else if type='F' then low=high-sumpercent;
else if percent>0 then low=sumpercent-percent;
run;
proc sgplot data=want;
highlow x=type high=high low=low / group=type type=bar
groupdisplay=cluster highlabel=percent lineattrs=graphoutlines
dataskin=matte;
xaxis display=(nolabel noticks);
yaxis offsetmin=0;
run;