Распределение по группам и блокам, со статистикой по оси

Я создавал шаблон GTL для бокса по группам и блокам времени. Я подозреваю, что GTL в SAS 9.4 (TS Level 1M2) еще не полностью поддерживает такую ​​многомерную, совмещенную по оси комбинацию BOXPLOT плюс BLOCKPLOT.

  • Если я ошибаюсь, я буду признателен за предложения о правильном подходе.
  • Если я прав, я приветствую предложения по более-менее прямому обходному решению GTL.

Приведенный ниже код создает первый график, но я действительно хочу второй график. Другими словами, я хочу, чтобы BLOCKPLOT поддерживал те же два уровня оси X, что и BOXPLOT (точка времени и группа обработки). Однако BLOCKPLOT будет складывать CLASS (группу лечения) только по оси X (момент времени). Но BOXPLOT разделит ГРУППЫ вдоль оси X внутри блоков.

Я не нахожу никакого способа перейти от "стекового" подхода BLOCKPLOT к "кластерному" подходу, подобному BOXPLOT. (Я тоже пробовал AXISTABLE, но они ведут себя как BLOCKPLOT.)

Спасибо, что указали на правильный подход или предложили обходной путь.

Представительные обсуждения я уже видел:

Сюжет из кода 9.4 (TS1M2) ниже: Сюжет из кода 9.4 (TS1M2) ниже

Очевидно манипулируемый сюжет, который я хотел бы закодировать: Очевидно манипулируемый сюжет, который я хочу от GTL

Код для первого сюжета:

/* Set up test data structure, with few seed observations */
  proc sql;
    create table labstruct
      (  mygroup         char(3) label='Treatment Group'
       , myvisitnum      num     label='Visit number'
       , myvisitname     char(8) label='Visit name'
       , labtestname     char(8) label='Name of lab test'
       , labseed         num     label='Lab measurement seed'
       , lablow          num     label='Low end of normal range'
       , labhigh         num     label='High end of normal range'
      )
    ;
    insert into labstruct
      values('A', 1,  'Day 1',  'Test XYZ', 48, 40, 60)
      values('B', 1,  'Day 1',  'Test XYZ', 52, 40, 60)
      values('A', 5,  'Week 1', 'Test XYZ', 50, 40, 60)
      values('B', 5,  'Week 1', 'Test XYZ', 50, 40, 60)
      values('A', 10, 'Week 2', 'Test XYZ', 52, 40, 60)
      values('B', 10, 'Week 2', 'Test XYZ', 48, 40, 60)
    ;
  quit;

  /* Make more obs from the seeds above */
    data labdata;
      set labstruct;

      do repeat = 1 to 20;
        labvalue = labseed + 6*rannor(3297);
        if ranuni(59843)>0.1 then output;
      end;

      label labvalue = 'Lab measurement';
      drop repeat labseed;
    run;


/* Calculate summary stats, and merge onto lab data for use as "block" labels */
  proc summary data=labdata noprint;
    by myvisitnum mygroup;
    var labvalue;
    output out=labstats (drop=_type_) 
           n=n mean=mean std=std;
  run;

  /* Merge summary stats onto lab data, used in GTL template as "block" labels */
  data labdata;
    merge labdata (in=in_data)
          labstats (in=in_stats);
    by myvisitnum mygroup;
    label n      = 'n'
          mean   = 'Mean'
          std    = 'Std Dev';
  run;


proc template;
  define statgraph xalignedstats;
    dynamic _TRT _AVISIT _AVISITN _AVAL _STAT1 _STAT2 _STAT3;

    begingraph / border=false dataskin=none attrpriority=none;

      layout overlay / walldisplay=none ;

        innermargin / align=top separator=false pad=(top=0);
          blockplot x=_AVISITN block=_AVISIT /
                    display=(outline values) valuefitpolicy=split ;
        endinnermargin;

        boxplot x=_AVISITN y=_AVAL /
                group=_TRT groupdisplay=cluster clusterwidth=0.8 ;

        innermargin / align=bottom separator=false pad=(bottom=0);
          blockplot x=_AVISITN block=_TRT / class=_TRT label='Treatment' filltype=alternate;
          blockplot x=_AVISITN block=_STAT1 / class=_TRT label='n' filltype=alternate;
          blockplot x=_AVISITN block=_STAT2 / class=_TRT label='Mean' filltype=alternate;
          blockplot x=_AVISITN block=_STAT3 / class=_TRT label='Std Dev' filltype=alternate;
        endinnermargin;

      endlayout;

    endgraph;
  end;
run;

proc sgrender data=labdata template=xalignedstats;
  dynamic 
          _TRT     ='mygroup'
          _AVISITN ='myvisitnum' 
          _AVISIT  ='myvisitname' 
          _AVAL    ='labvalue'
          _STAT1   ='n'
          _STAT2   ='mean'
          _STAT3   ='std'
          ;
run;

1 ответ

Решение

По крайней мере, суть этого - ответственность. Если вы используете axistable вместо blockplot, у вас есть возможность указать classdisplay=cluster, который действует аналогично groupdisplay=cluster (почему имена разные, понятия не имею).

proc template;
  define statgraph xalignedstats;
    dynamic _TRT _AVISIT _AVISITN _AVAL _STAT1 _STAT2 _STAT3;

    begingraph / border=false dataskin=none attrpriority=none;

      layout overlay / walldisplay=none ;

        innermargin / align=top separator=false pad=(top=0);
          blockplot x=_AVISITN block=_AVISIT /
                    display=(outline values) valuefitpolicy=split ;
        endinnermargin;

        boxplot x=_AVISITN y=_AVAL /
                group=_TRT groupdisplay=cluster clusterwidth=0.8 ;

        innermargin / align=bottom separator=false pad=(bottom=0);
          axistable x=_AVISITN value=_TRT / class=_TRT label='Treatment' classdisplay=cluster colorgroup=_TRT;
          axistable x=_AVISITN value=_STAT1 / class=_TRT label='n'  classdisplay=cluster colorgroup=_TRT;
          axistable x=_AVISITN value=_STAT2 / class=_TRT label='Mean' classdisplay=cluster colorgroup=_TRT;
          axistable x=_AVISITN value=_STAT3 / class=_TRT label='Std Dev' classdisplay=cluster colorgroup=_TRT;
        endinnermargin;

      endlayout;

    endgraph;
  end;
run;

Вам может быть труднее (или невозможно) получить правильное форматирование, например чередующиеся цвета, но это, по крайней мере, начало. Вы можете посмотреть на использование colorgroup чтобы цвета соответствовали цветам вашей линии, например, несмотря на отсутствие (много / вообще) контроля над заливкой фона.

Другие вопросы по тегам