SAS中多维数组的每个切片的MAX

时间:2018-09-26 00:14:24

标签: arrays sas

我正在尝试建立一种逻辑,以在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;

我需要为数组t_appt_buracc_RpymtStatPrd的第一维的每个值找到第二和第三维的最大值。 希望有道理。 谢谢

1 个答案:

答案 0 :(得分:2)

您可能需要重新考虑您的想法。您需要最大2*10 + 2*24 + 10*24 = 308个成对的尺寸交叉。宏无疑是在DATA步骤中对最大确定进行编码生成的最佳方法。手动编码该解决方案极易出现复制粘贴错误和一般脱发。

更好的程序方法是将所有的恶作剧转置为向量,按维名称分类,然后让Proc MEANSSUMMARYUNIVARIATE计算成对交叉的最大值,就像使用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();

在转置转换后对每个杂交进行Pro 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;