MAX каждого среза многомерного массива в SAS - PullRequest
0 голосов
/ 26 сентября 2018

Я пытаюсь выработать логику, чтобы найти максимум каждого среза в многомерном массиве в sas.

array max_appt_buracc1_RpymtStatPrd(2,10)
    max_appt1_buracc1_RpymtStatPrd1 - max_appt1_buracc1_RpymtStatPrd10
    max_appt2_buracc1_RpymtStatPrd1 - max_appt2_buracc1_RpymtStatPrd10;

array t_appt_buracc_RpymtStatPrd(2,10,24) 
    t_appt1_buracc1_RpymtStatPrd1 - t_appt1_buracc1_RpymtStatPrd24 
    t_appt1_buracc2_RpymtStatPrd1 - t_appt1_buracc2_RpymtStatPrd24
    t_appt1_buracc3_RpymtStatPrd1 - t_appt1_buracc3_RpymtStatPrd24
    t_appt1_buracc4_RpymtStatPrd1 - t_appt1_buracc4_RpymtStatPrd24
    t_appt1_buracc5_RpymtStatPrd1 - t_appt1_buracc5_RpymtStatPrd24
    t_appt1_buracc6_RpymtStatPrd1 - t_appt1_buracc6_RpymtStatPrd24
    t_appt1_buracc7_RpymtStatPrd1 - t_appt1_buracc7_RpymtStatPrd24
    t_appt1_buracc8_RpymtStatPrd1 - t_appt1_buracc8_RpymtStatPrd24
    t_appt1_buracc9_RpymtStatPrd1 - t_appt1_buracc9_RpymtStatPrd24
    t_appt1_buracc10_RpymtStatPrd1 - t_appt1_buracc10_RpymtStatPrd24

    t_appt2_buracc1_RpymtStatPrd1 - t_appt2_buracc1_RpymtStatPrd24 
    t_appt2_buracc2_RpymtStatPrd1 - t_appt2_buracc2_RpymtStatPrd24
    t_appt2_buracc3_RpymtStatPrd1 - t_appt2_buracc3_RpymtStatPrd24
    t_appt2_buracc4_RpymtStatPrd1 - t_appt2_buracc4_RpymtStatPrd24
    t_appt2_buracc5_RpymtStatPrd1 - t_appt2_buracc5_RpymtStatPrd24
    t_appt2_buracc6_RpymtStatPrd1 - t_appt2_buracc6_RpymtStatPrd24
    t_appt2_buracc7_RpymtStatPrd1 - t_appt2_buracc7_RpymtStatPrd24
    t_appt2_buracc8_RpymtStatPrd1 - t_appt2_buracc8_RpymtStatPrd24
    t_appt2_buracc9_RpymtStatPrd1 - t_appt2_buracc9_RpymtStatPrd24
    t_appt2_buracc10_RpymtStatPrd1 - t_appt2_buracc10_RpymtStatPrd24;
do indexp=1 to 2;
do i=1 o 10;
do j=1 to 24;
max_appt_buracc1_RpymtStatPrd(indexp,i,j) = whichn(max( of t_appt_buracc_RpymtStatPrd(indexp,i,*) ),of t_appt_buracc_RpymtStatPrd(indexp,i,*));
end;
end;
end;

Мне нужно найти максимум комбинации 2-й и 3-й димерсионов для каждогозначение первых измерений массива t_appt_buracc_RpymtStatPrd.Надеюсь, что это имеет смысл.Спасибо

1 Ответ

0 голосов
/ 26 сентября 2018

Возможно, вам придется переосмыслить то, о чем вы можете думать.Есть пары парных размерных пересечений 2*10 + 2*24 + 10*24 = 308, для которых вы хотите получить максимумы.Макрос, безусловно, является лучшим способом кодирования максимального определения в шаге DATA.Ручное кодирование решения очень склонно к копированию ошибок вставки и общего выпадения волос.

Гораздо лучшим процедурным способом было бы транспонировать все махинации в вектор, категоричный по пространственному имени и позволяющийProc MEANS, SUMMARY или UNIVARIATE вычисляют максимумы для парных пересечений, как было бы сделано с оператором WAYS 2.

В примерах кода показаны оба подхода и выполняется Proc COMPARE … OUT= OUTNOEQUAL дляПокажите, что результирующее вычисление максимума для каждого размерного пересечения является идентичным.(Т.е. данные OUT= не имеют строк, что означает, что все переменные с одинаковыми именами имеют абсолютно одинаковые значения)

Некоторые данные с несколькими экземплярами массива 3 измерений (1 строка на экземпляр)

%macro make_data (
  out=have,
  dim1=x, count1=2,
  dim2=y, count2=10,
  dim3=z, count3=24
);
  %local index1 index2;

  data have;
    length rownum 8;

    array cells(&count1,&count2,&count3)
    %do index1 = 1 %to &count1;
    %do index2 = 1 %to &count2;
      &dim1.&index1._&dim2.&index2._&dim3.1 - &dim1.&index1._&dim2.&index2._&dim3.&count3 
    %end;
    %end;
    (1:%eval(&count1*&count2*&count3));

    rownum = 1;
    output;

    do rownum = rownum+1 to 10;
      array cells_flat x:;
      do _n_ = 1 to dim(cells_flat);
        cells_flat(_n_) = cells_flat(_n_) + dim(cells_flat);
      end;
      output;
    end;

    drop _:;
  run;
%mend;

options mprint;

%make_data();

Макрос кодирует формулу MAX () для каждого пересечения

%macro every_which_way (
  data=have,
  out=want,
  dim1=x, count1=2,
  dim2=y, count2=10,
  dim3=z, count3=24
);
  data &out;
    set &data;

    %local index1 index2 item1 item2 item3 crossing;
    %local map1 map2 map3;

    %local map&dim1. ; %let map&dim1. = 1;
    %local map&dim2. ; %let map&dim2. = 2;
    %local map&dim3. ; %let map&dim3. = 3;
/*
    array cells(&count1,&count2,&count3)
    %do index1 = 1 %to &count1;
    %do index2 = 1 %to &count2;
      &dim1.&index1._&dim2.&index2._&dim3.1 - &dim1.&index1._&dim2.&index2._&dim3.&count3 
    %end;
    %end;
    ;
*/
    %* item 1 & 2 are dimensions, for pairwise crossing; 

    %do item1 = 1 %to 2;
      %let map1 = &&&&map&&dim&item1;

      %do item2 = %eval(&item1+1) %to 3;
      %let map2 = &&&&map&&dim&item2;

        %* item3 is dimension being measured for max;

        %let item3 = %eval (1 + 2 + 3 - &item1 - &item2);
        %let map3 = &&&&map&&dim&item3;

        %* for each level of the crossed dimensions;

        %do index1 = 1 %to &&count&item1..;
        %do index2 = 1 %to &&count&item2..;

          %let crossing = &&dim&item1..&index1._&&dim&item2..&index2.;

          %* data set variable MAX_OVER_<item1-dimension><item1-index>_<item2-dimension><item2-index>;
          max_over_&crossing. = MAX ( .
            %do index3 = 1 %to &&count&item3..;

              %local addr1 addr2 addr3;

              %let addr&map1 = &&dim&item1..&index1.;
              %let addr&map2 = &&dim&item2..&index2.;
              %let addr&map3 = &&dim&item3..&index3.;

              , &addr1._&addr2._&addr3.

            %end;
          );

        %end;
        %end;
      %end;
    %end;

  run;
%mend;

%every_which_way();

Proc MEANS вычисление каждого пересечения после транспозиционного преобразования

proc transpose data=have out=have_vector;
  by rownum;
run;

data have_vector_view / view=have_vector_view;
  set have_vector;
  dim1 = scan (_name_,1,'_');
  dim2 = scan (_name_,2,'_');
  dim3 = scan (_name_,3,'_');
run;

proc means noprint data=have_vector_view;
  by rownum;
  class dim1 dim2 dim3;
  ways 2;
  var col1;
  output out=want_max max=max;
run;

data want_max_prepivot_view / view=want_max_prepivot_view;
  set want_max;
  _name_ = catx('_', of dim:);
run;

proc transpose data=want_max_prepivot_view out=want_max_wide(drop=_name_) prefix=max_over_;
  by rownum;
  id _name_;
  var max;
run;

И сравнение методов

proc compare noprint base=want compare=want_max_wide out=differences outnoequal;
  by rownum;
run;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...