SAS GRAPH: выровнять ось для 2 графиков с решетками
Я действительно борюсь с этой проблемой, я действительно не могу найти решение, и я надеюсь, что, разместив здесь, кто-то поможет.
Проблема в том, что с этим шаблоном с двумя решетками я не могу выровнять ось.
Теперь я подробно опишу все, что я сделал с кодом для воспроизведения каждого шага:
Здесь приведен код как для графика, так и для примера набора данных (это простая версия: http://support.sas.com/kb/39/092.html).
Примерный набор данных:
data immune;
format sival f6.3;
input trt $ 1-8 cyc $ 10-18 pt lbparm $ xval sival;
cards;
Drug A Cycle 1 1 C3 1 1.120
Drug A Cycle 1 1 C4 1 0.147
Drug A Cycle 1 1 C3 2 1.080
Drug A Cycle 1 1 C4 2 0.131
Drug A Cycle 1 1 C3 3 0.887
Drug A Cycle 1 1 C4 3 0.113
Drug A Cycle 2 1 C3 4 1.440
Drug A Cycle 2 1 C4 4 0.278
Drug A Cycle 2 1 C3 5 1.180
Drug A Cycle 2 1 C4 5 0.234
Drug A Cycle 2 1 C3 6 1.360
Drug A Cycle 2 1 C4 6 0.281
Drug A Cycle 3 1 C3 7 1.190
Drug A Cycle 3 1 C4 7 0.282
Drug A Cycle 3 1 C3 8 1.000
Drug A Cycle 3 1 C4 8 0.228
Drug A Cycle 3 1 C3 9 1.040
Drug A Cycle 3 1 C4 9 0.228
Drug A Cycle 4 1 C3 10 0.917
Drug A Cycle 4 1 C4 10 0.163
Drug A Cycle 4 1 C3 11 0.789
Drug A Cycle 4 1 C4 11 0.136
Drug A Cycle 4 1 C3 12 0.861
Drug A Cycle 4 1 C4 12 0.148
Drug A Cycle 1 2 C3 1 1.180
Drug A Cycle 1 2 C4 1 0.264
Drug A Cycle 1 2 C3 2 0.942
Drug A Cycle 1 2 C4 2 0.184
Drug A Cycle 1 2 C3 3 1.010
Drug A Cycle 1 2 C4 3 0.160
Drug A Cycle 2 2 C3 4 1.050
Drug A Cycle 2 2 C4 4 0.134
Drug A Cycle 2 2 C3 5 0.980
Drug A Cycle 2 2 C4 5 0.120
Drug A Cycle 2 2 C3 6 1.020
Drug A Cycle 2 2 C4 6 0.126
Drug A Cycle 3 2 C3 7 0.961
Drug A Cycle 3 2 C4 7 0.110
Drug A Cycle 3 2 C3 8 0.859
Drug A Cycle 3 2 C4 8 0.091
Drug A Cycle 3 2 C3 9 0.928
Drug A Cycle 3 2 C4 9 0.097
Drug A Cycle 4 2 C3 10 1.380
Drug A Cycle 4 2 C4 10 0.330
Drug A Cycle 4 2 C3 11 1.210
Drug A Cycle 4 2 C4 11 0.281
Drug A Cycle 4 2 C3 12 1.180
Drug A Cycle 4 2 C4 12 0.278
Drug A Cycle 1 3 C3 1 1.180
Drug A Cycle 1 3 C4 1 0.269
Drug A Cycle 1 3 C3 2 1.010
Drug A Cycle 1 3 C4 2 0.213
Drug A Cycle 1 3 C3 3 1.040
Drug A Cycle 1 3 C4 3 0.200
Drug A Cycle 2 3 C3 4 1.200
Drug A Cycle 2 3 C4 4 0.332
Drug A Cycle 2 3 C4 5 0.371
Drug A Cycle 2 3 C4 6 0.316
Drug A Cycle 3 3 C4 7 0.271
Drug A Cycle 3 3 C3 8 1.050
Drug A Cycle 3 3 C4 8 0.246
Drug A Cycle 3 3 C3 9 1.100
Drug A Cycle 3 3 C4 9 0.248
Drug A Cycle 4 3 C3 10 1.090
Drug A Cycle 4 3 C4 10 0.234
Drug A Cycle 4 3 C3 11 0.937
Drug A Cycle 4 3 C3 12 0.980
Drug A Cycle 1 4 C3 1 1.220
Drug A Cycle 1 4 C4 1 0.182
Drug A Cycle 1 4 C3 2 0.983
Drug A Cycle 1 4 C4 2 0.132
Drug A Cycle 1 4 C3 3 0.979
Drug A Cycle 1 4 C4 3 0.128
Drug A Cycle 2 4 C3 4 1.190
Drug A Cycle 2 4 C4 4 0.134
Drug A Cycle 2 4 C3 5 1.010
Drug A Cycle 2 4 C4 5 0.076
Drug A Cycle 2 4 C3 6 1.100
Drug A Cycle 2 4 C4 6 0.083
Drug A Cycle 3 4 C3 7 1.140
Drug A Cycle 3 4 C4 7 0.108
Drug A Cycle 3 4 C3 8 1.140
Drug A Cycle 3 4 C4 8 0.104
Drug A Cycle 3 4 C3 9 1.120
Drug A Cycle 3 4 C4 9 0.080
;
run;
proc sort data=immune out=sasuser.immune;
by pt;
run;
Теперь код шаблона для графика:
proc template;
define statgraph gsv00251;
begingraph / designwidth=7in designheight=4.5in;
entrytitle 'Immunology Profile by Treatment';
layout gridded;
layout datalattice rowvar=lbparm /
headerlabeldisplay=value includemissingclass=false
columnaxisopts=(label="Cycle Day" griddisplay=on type=discrete
discreteopts=(tickdisplaylist=
("0" "15" "30" "0" "15" "30" "0" "15" "30" "0" "15" "30"))
offsetmin = .03 offsetmax = .03)
rowaxisopts=(offsetmax=.1 label="Values Converted to SI Units "
griddisplay=on) rowdatarange=union;
layout prototype;
blockplot x=xval block=cyc / datatransparency = .75
display=(outline fill )
name="block" filltype=alternate;
seriesplot x=xval y=sival / group=pt index=pt name='a'
display=all lineattrs=(pattern=1 thickness=2)
markerattrs=(symbol=circlefilled size=8);
endlayout;
endlayout;
entry ' ';
discretelegend 'a' / title='Patient' across=8;
endlayout;
endgraph;
end;
run;
Теперь я хотел бы добавить некоторую информацию в верхнюю часть каждого блока, поэтому я провел поиск в Интернете и обнаружил, что лучший способ достичь этого результата - это изменить шаблон proc, добавив 2 строки решетки:
1) первая строка решетки, содержащая блок-график с такой информацией, как на этом графике https://support.sas.com/documentation/cdl/en/grstatug/62464/HTML/default/viewer.htm (один с ящиками и статистикой, второй пример).
2) вторая строка решетки, содержащая ранее размещенный участок.
Поэтому я создал этот необработанный примерный набор данных:
data firstrow;
length ROW $20 TITLE $20 REASON $50 CHAR $20 VAR $20;
infile datalines dlm=',';
input ROW TITLE REASON CHAR VAR;
datalines;
ROW 1,ROW 1,FIRST REASON,FIRST ROW,FIRST VAR,
ROW 2,ROW 2,SECOND REASON,SECOND ROW,SECOND VAR,
ROW 3,ROW 3,THIRD REASON,THIRD ROW,THIRD VAR,
ROW 4,ROW 4,FOURTH REASON,FOURTH ROW,FOURTH VAR,
;
proc transpose data=firstrow out=firstrow_;
by row;
var title reason char var;
run;
и объединил (нет) с предыдущим набором данных:
proc sort data=immune out=immune;
by pt;
run;
data immune;
merge immune firstrow_;
run;
затем изменил процедуру добавления шаблона layout lattice
и блокплот.
proc template;
define statgraph gsv00251;
begingraph / designwidth=7in designheight=4.5in;
entrytitle 'Immunology Profile by Treatment';
layout lattice / columns=1 rowweights=(.15 .85);
blockplot x=row block=col1 / class=_name_
datatransparency = .75
display=(outline fill values label)
name="stats" filltype=alternate
valuehalign=center
includemissingclass=false
labelattrs=GraphDataText valueattrs=GraphDataText ;
layout gridded;
layout datalattice rowvar=lbparm /
headerlabeldisplay=value includemissingclass=false
columnaxisopts=(label="Cycle Day" griddisplay=on type=discrete
discreteopts=(tickdisplaylist=
("0" "15" "30" "0" "15" "30" "0" "15" "30" "0" "15" "30"))
offsetmin = .03 offsetmax = .03)
rowaxisopts=(offsetmax=.1 label="Values Converted to SI Units "
griddisplay=on) rowdatarange=union;
layout prototype;
blockplot x=xval block=cyc / datatransparency = .75
display=(outline fill )
name="block" filltype=alternate;
seriesplot x=xval y=sival / group=pt index=pt name='a'
display=all lineattrs=(pattern=1 thickness=2)
markerattrs=(symbol=circlefilled size=8);
endlayout;
endlayout;
entry ' ';
discretelegend 'a' / title='Patient' across=8;
endlayout;
endlayout;
endgraph;
end;
run;
Результат хороший, но не менее важный, я имею в виду, ось столбца не выровнена по двум графикам, результат - первый опубликованный график.
Есть в основном 2 проблемы: метки заголовка справа и метки оси слева. Как я могу изменить этот сюжет, чтобы получить правильный результат? (ось выровнена)
Так как я разместил много кода, здесь вы найдете только окончательный вариант всего этого
data immune;
format sival f6.3;
input trt $ 1-8 cyc $ 10-18 pt lbparm $ xval sival;
cards;
Drug A Cycle 1 1 C3 1 1.120
Drug A Cycle 1 1 C4 1 0.147
Drug A Cycle 1 1 C3 2 1.080
Drug A Cycle 1 1 C4 2 0.131
Drug A Cycle 1 1 C3 3 0.887
Drug A Cycle 1 1 C4 3 0.113
Drug A Cycle 2 1 C3 4 1.440
Drug A Cycle 2 1 C4 4 0.278
Drug A Cycle 2 1 C3 5 1.180
Drug A Cycle 2 1 C4 5 0.234
Drug A Cycle 2 1 C3 6 1.360
Drug A Cycle 2 1 C4 6 0.281
Drug A Cycle 3 1 C3 7 1.190
Drug A Cycle 3 1 C4 7 0.282
Drug A Cycle 3 1 C3 8 1.000
Drug A Cycle 3 1 C4 8 0.228
Drug A Cycle 3 1 C3 9 1.040
Drug A Cycle 3 1 C4 9 0.228
Drug A Cycle 4 1 C3 10 0.917
Drug A Cycle 4 1 C4 10 0.163
Drug A Cycle 4 1 C3 11 0.789
Drug A Cycle 4 1 C4 11 0.136
Drug A Cycle 4 1 C3 12 0.861
Drug A Cycle 4 1 C4 12 0.148
Drug A Cycle 1 2 C3 1 1.180
Drug A Cycle 1 2 C4 1 0.264
Drug A Cycle 1 2 C3 2 0.942
Drug A Cycle 1 2 C4 2 0.184
Drug A Cycle 1 2 C3 3 1.010
Drug A Cycle 1 2 C4 3 0.160
Drug A Cycle 2 2 C3 4 1.050
Drug A Cycle 2 2 C4 4 0.134
Drug A Cycle 2 2 C3 5 0.980
Drug A Cycle 2 2 C4 5 0.120
Drug A Cycle 2 2 C3 6 1.020
Drug A Cycle 2 2 C4 6 0.126
Drug A Cycle 3 2 C3 7 0.961
Drug A Cycle 3 2 C4 7 0.110
Drug A Cycle 3 2 C3 8 0.859
Drug A Cycle 3 2 C4 8 0.091
Drug A Cycle 3 2 C3 9 0.928
Drug A Cycle 3 2 C4 9 0.097
Drug A Cycle 4 2 C3 10 1.380
Drug A Cycle 4 2 C4 10 0.330
Drug A Cycle 4 2 C3 11 1.210
Drug A Cycle 4 2 C4 11 0.281
Drug A Cycle 4 2 C3 12 1.180
Drug A Cycle 4 2 C4 12 0.278
Drug A Cycle 1 3 C3 1 1.180
Drug A Cycle 1 3 C4 1 0.269
Drug A Cycle 1 3 C3 2 1.010
Drug A Cycle 1 3 C4 2 0.213
Drug A Cycle 1 3 C3 3 1.040
Drug A Cycle 1 3 C4 3 0.200
Drug A Cycle 2 3 C3 4 1.200
Drug A Cycle 2 3 C4 4 0.332
Drug A Cycle 2 3 C4 5 0.371
Drug A Cycle 2 3 C4 6 0.316
Drug A Cycle 3 3 C4 7 0.271
Drug A Cycle 3 3 C3 8 1.050
Drug A Cycle 3 3 C4 8 0.246
Drug A Cycle 3 3 C3 9 1.100
Drug A Cycle 3 3 C4 9 0.248
Drug A Cycle 4 3 C3 10 1.090
Drug A Cycle 4 3 C4 10 0.234
Drug A Cycle 4 3 C3 11 0.937
Drug A Cycle 4 3 C3 12 0.980
Drug A Cycle 1 4 C3 1 1.220
Drug A Cycle 1 4 C4 1 0.182
Drug A Cycle 1 4 C3 2 0.983
Drug A Cycle 1 4 C4 2 0.132
Drug A Cycle 1 4 C3 3 0.979
Drug A Cycle 1 4 C4 3 0.128
Drug A Cycle 2 4 C3 4 1.190
Drug A Cycle 2 4 C4 4 0.134
Drug A Cycle 2 4 C3 5 1.010
Drug A Cycle 2 4 C4 5 0.076
Drug A Cycle 2 4 C3 6 1.100
Drug A Cycle 2 4 C4 6 0.083
Drug A Cycle 3 4 C3 7 1.140
Drug A Cycle 3 4 C4 7 0.108
Drug A Cycle 3 4 C3 8 1.140
Drug A Cycle 3 4 C4 8 0.104
Drug A Cycle 3 4 C3 9 1.120
Drug A Cycle 3 4 C4 9 0.080
;
run;
data firstrow;
length ROW $20 TITLE $20 REASON $50 CHAR $20 VAR $20;
infile datalines dlm=',';
input ROW TITLE REASON CHAR VAR;
datalines;
ROW 1,ROW 1,FIRST REASON,FIRST ROW,FIRST VAR,
ROW 2,ROW 2,SECOND REASON,SECOND ROW,SECOND VAR,
ROW 3,ROW 3,THIRD REASON,THIRD ROW,THIRD VAR,
ROW 4,ROW 4,FOURTH REASON,FOURTH ROW,FOURTH VAR,
;
proc transpose data=firstrow out=firstrow_;
by row;
var title reason char var;
run;
proc sort data=immune out=immune;
by pt;
run;
data immune;
merge immune firstrow_;
run;
proc template;
define statgraph gsv00251;
begingraph / designwidth=7in designheight=4.5in;
entrytitle 'Immunology Profile by Treatment';
layout lattice / columns=1 rowweights=(.15 .85);
columnaxes;
columnaxis / display=(ticks tickvalues);
endcolumnaxes;
blockplot x=row block=col1 / class=_name_
datatransparency = .75
display=(outline fill values label)
name="stats" filltype=alternate
valuehalign=center
includemissingclass=false
labelattrs=GraphDataText valueattrs=GraphDataText ;
layout gridded;
layout datalattice rowvar=lbparm /
headerlabeldisplay=value includemissingclass=false
columnaxisopts=(label="Cycle Day" griddisplay=on type=discrete
discreteopts=(tickdisplaylist=
("0" "15" "30" "0" "15" "30" "0" "15" "30" "0" "15" "30"))
offsetmin = .03 offsetmax = .03)
rowaxisopts=(offsetmax=.1 label="Values Converted to SI Units "
griddisplay=on) rowdatarange=union;
layout prototype;
blockplot x=xval block=cyc / datatransparency = .75
display=(outline fill )
name="block" filltype=alternate;
seriesplot x=xval y=sival / group=pt index=pt name='a'
display=all lineattrs=(pattern=1 thickness=2)
markerattrs=(symbol=circlefilled size=8);
endlayout;
endlayout;
entry ' ';
discretelegend 'a' / title='Patient' across=8;
endlayout;
endlayout;
endgraph;
end;
run;
ods listing close;
ods html image_dpi=100 file='Immunology.html' path='.';
ods graphics / reset noborder width=600px height=400px
imagename='ClinicalHandout_Immunology' imagefmt=gif noscale;
proc sgrender data=immune template=gsv00251;
run;
ods html close;
ods listing;
1 ответ
Из перекрестной ветки в сообществе sas (спасибо, Санджай). https://communities.sas.com/t5/SAS-GRAPH-and-ODS-Graphics/SAS-Graph-Align-axis-with-lattice-rows/m-p/229696
При использовании внешнего контейнера LAYOUT LATTICE с отдельными ячейками для блочного графика и графика DATAPANEL выравнивание между осями содержащихся графиков не выполняется. Сюжеты не знают друг о друге.
BLOCKPLOT на панели имеет X=XVAL, в то время как BLOCKPLOT вверху имеет X=ROW. Это независимые переменные. Кроме того, верхний график является автономным и не нуждается в резервировании места для заголовков строк в нижней части.
Лучший способ сделать это - избегать использования панели данных. Используйте одну LATOUT LATTICE с тремя рядами. В двух нижних строках будут представлены графики серий для данных "C3" и "C4". Вы можете использовать выражения для извлечения только данных для одного значения LBPARM. Используйте INSET или ROWHWADER, чтобы разместить значение класса. В верхней строке будет статистика с использованием блочного графика или AxisTable. убедитесь, что переменные x одинаковы или похожи.
Полезно знать, какую версию SAS вы используете. Будет проще с SAS 9.4M3.