是否可以在数组语句中使用表?

时间:2017-06-06 15:28:25

标签: sas

我正在尝试引用数组中的表,以便最终在数据步骤中使用。这是代码:

proc sql;
create table claims.iterations 
    as select Allowed_Claims, Px1 
    from simulation 
    order by Allowed_Claims, Px1;
quit;
data simulation_iterations;
    array Members {24} _temporary_ (5 6 8 10 12 15 20 25 30 40 50 60 70 80 
                                    90 100 125 150 175 200 250 300 400 500); 
    array ****** ;
    do i = 1 to 24;
    do j = 1 to Members{i}-1;
        Px2 = rand('Uniform',0,1);
        if Px2 > 0.5 then Px2=Px2;          
        output;
        end;
    output;
    end;
run;

可以这样做吗?虽然没有显示,但是我想使用该表来尝试线性插值“Members”数组中的值。

编辑:

我想基于随机生成的值(从0到1)插入Allowed_Claims。我将基于线性插值的浓缩表列在下面。

Allowed_Claims  Px1
25.224545313    0.0008129708
34.767797696    0.0014747668
35.367278291    0.0015210493
42.616660238    0.0021191153
52.495185148    0.0030343735
52.652599162    0.0030497846
53.26904904     0.0031103676
57.183442582    0.0035034118

例如,让我们调用此进程A,如果Px2 = rand('Uniform',0,1)得到.0010,我希望它在Allowed_Claims值之间进行插值,其中Px1 = 0.0008129708和Px1 = 0.0014747668。

数组的作用是它决定了我想要的进程A的迭代次数。数组是

Members {24} _temporary_ (5 6 8 10 12 15 20 25 30 40 50 60 70 80 
                                    90 100 125 150 175 200 250 300 400 500);

因此,当循环开始时,它将执行过程A的5次迭代,从而产生5个内插的“allowed_claims”值。我想要这五个主张的平均值。

然后,循环将继续并执行6次迭代的过程A并产生6个内插的“allowed_claims”值。同样,我想要这六项索赔的平均值。

我希望输出表看起来像:

`

Member[i]    Average_Expected_Claims
   5              (average of 5 interpolated claims) 
   6              (average of 6 interpolated claims) 
   8              (average of 8 interpolated claims) 

2 个答案:

答案 0 :(得分:1)

以下是如何使用哈希表执行此操作的示例。它与此用法中的数组非常相似 - 因为没有“查找键”,我们只需加载它并创建一个迭代器,然后循环遍历迭代器,就像一个数组(除了你不能抓住确切的位置)。遗憾的是,没有VLOOKUP类型的功能可以为您提供最接近的匹配 - 您必须进行迭代才能找到正确的匹配。

这不是绝对最有效的过程,特别是我做了一个比我需要的更多的迭代器调用(因为我可以在变量中存储最后看到的允许的声明)。我不打扰因为坦率地说它不值得,只是再次调用迭代器并没有太大的区别,但我认为如果你的机器需要很长时间,那么效率可能会有所不同。我怀疑它会。

*Just setting up the example iterations dataset;
data iterations;
  call streaminit(7);
  retain allowed_claims 20;
  do px1 = 0.05 to 1 by 0.05;
    allowed_claims + rand('Uniform')*5;
    output;
  end;
run;


data simulated_iterations2;
  call streaminit(8);      *init the random generator;
  array Members [5] _temporary_ (5 6 8 10 12);  *any number of members here is fine;
  if _n_ eq 1  then do;            *initialize the hash tables;
    if 0 then set iterations;      *defines the variables used;
    declare hash _iter(dataset:'iterations', ordered:'a');  *ordered = ascending - do not need a sort first;
    _iter.defineKey('px1');                    * key is artificial, but has to exist;
    _iter.defineData('px1','allowed_Claims');  * data variables to retrieve;
    _iter.defineDone();
    declare hiter hi_iter('_iter');            * the iterator object;

  end;

  do _i_member = 1 to dim(members);            * iterate over members array;
    call missing(claims_simulated);
    do _i_simul = 1 to members[_i_member];     * iterate for the member value;

      rand_value = rand('Uniform');            * the number to interpolate;
      do rc= hi_iter.first() by 0 until (hi_iter.next() ne 0 or px1 gt rand_value );
         *do nothing;                          * here we are doing the work in the DO statement, looping until we find the value greater than the rand value;
      end;
      ac_max = allowed_claims;                 * your 'max' interpolation value;
      rc = hi_iter.prev();                     * back up one;
      ac_min = allowed_claims;                 * your 'min' interpolation value;
      claims_simulated + (mean(ac_min,ac_max))/members[_i_member];  *add the mean of the two interpolation values divided by the total number we are going to do to the total - avoids us having to do another array to store these and get mean of;
      put rand_value= claims_simulated=;       *just for logging;
    end;
    putlog;
    output;
  end;

  stop;

run;

答案 1 :(得分:0)

不,这样做是不可能的,但有hash tables的概念,这是完成相同类型查找的合适解决方案。

SAS中的数组基本上是变量名称列表,它们不是C#中的实际数据类型。