SAS:根据减少的月份获取数字列表

SAS:根据减少的月份获取数字列表,sas,enterprise-guide,Sas,Enterprise Guide,我有这些数据 data have; input cust_id pmt months; datalines; AA 100 0 AA 50 1 AA 200 2 AA 350 3 AA 150 4 AA 700 5 BB 500 0 BB 300 1 BB 1000 2 BB 800 3 run; 我想生成一个如下的输出 data want; input cust_i

我有这些数据

    data have;
    input cust_id pmt months;
    datalines;
    AA 100 0
    AA 50 1
    AA 200 2
    AA 350 3
    AA 150 4
    AA 700 5
    BB 500 0
    BB 300 1
    BB 1000 2
    BB 800 3
    run;
我想生成一个如下的输出

    data want;
    input cust_id pmt months i;
    datalines;
    AA 100 0 0
    AA 50 0 1
    AA 200 0 2
    AA 350 0 3
    AA 150 0 4
    AA 700 0 5
    AA 50 1 0
    AA 200 1 1
    AA 350 1 2
    AA 150 1 3
    AA 700 1 4
    AA 200 2 0
    AA 350 2 1
    AA 150 2 2
    AA 700 2 3
    AA 350 3 0
    AA 150 3 1
    AA 700 3 2
    AA 150 4 0
    AA 700 4 1
    AA 700 5 0
    BB 500 0 0
    BB 300 0 1
    BB 1000 0 2
    BB 800 0 3
    BB 300 1 0
    BB 1000 1 1
    BB 800 1 2
    BB 1000 2 0
    BB 800 2 1
    BB 800 3 0
    run;
    data temp1;
    set have;
    do i = 0 to maxval;
    if (months <=maxval) then output;
    end;
有几千行具有不同的
cust\u ID
和不同的
month
长度。我试着加入表格,但它无法让我得到100 50 200 350 150 700的序列(对于cust_ID AA)。如果我的
月数
为0,我只能复制100;如果
月数
为1,我只能复制50,依此类推。我创建了一个
maxval
,它是最大月份值。我的代码是这样的

    data want;
    input cust_id pmt months i;
    datalines;
    AA 100 0 0
    AA 50 0 1
    AA 200 0 2
    AA 350 0 3
    AA 150 0 4
    AA 700 0 5
    AA 50 1 0
    AA 200 1 1
    AA 350 1 2
    AA 150 1 3
    AA 700 1 4
    AA 200 2 0
    AA 350 2 1
    AA 150 2 2
    AA 700 2 3
    AA 350 3 0
    AA 150 3 1
    AA 700 3 2
    AA 150 4 0
    AA 700 4 1
    AA 700 5 0
    BB 500 0 0
    BB 300 0 1
    BB 1000 0 2
    BB 800 0 3
    BB 300 1 0
    BB 1000 1 1
    BB 800 1 2
    BB 1000 2 0
    BB 800 2 1
    BB 800 3 0
    run;
    data temp1;
    set have;
    do i = 0 to maxval;
    if (months <=maxval) then output;
    end;
关于如何生成我的需求表,有什么想法或不同的方法吗?谢谢大家!

尝试以下操作:

data want(drop = start_obs limit j);
   retain start_obs 1;

   /* read by cust_id group */
   do until(last.cust_id);
      set have end = last_obs;
      by cust_id;
   end;

   limit = months;

   do j = 0 to limit;
      i = 0;

      do obs_num = start_obs + j to start_obs + limit;
         /* read specific observations using direct access */
         set have point = obs_num;

         months = j;
         output;
         i = i + 1;
      end;
   end;

   /* prepare for next direct access read */
   start_obs = limit + 2;

   if last_obs then
      stop;

run;

这个问题有点棘手,因为事情有三个方向

  • 组重复次数从组计数下降。在每次重复中:
    • 付款项目开始索引上升并在组计数时终止
    • 月份(as I)项目开始索引为1,终止从组计数下降
SQL

一种SQL方法是组内的三向自反连接。
months
值作为组内索引,必须从0单调1才能起作用

proc sql;
  create table want as 
  select X.cust_id, Z.pmt, X.months, Y.months as i
  from have as X
  join have as Y on X.cust_id = Y.cust_id
  join have as Z on Y.cust_id = Z.cust_id
  where  
    X.months + Y.months = Z.months
  order by
    X.cust_id, X.months, Z.months
  ;
quit;
数据步骤

DOW循环用于计算组大小。2-深循环穿过组合,并计算三个
点=
值(finagled)以检索相关值

data want2;
  if 0 then set have; * prep pdv to match have;

  retain point_end ;

  point_start = sum(point_end,0);

  do group_count = 1 by 1 until (last.cust_id);
    set have(keep=cust_id);
    by cust_id;
  end;

  do index1 = 1 to group_count;

    point1 = point_start + index1;
    set have (keep=months) point = point1;

    do index2 = 0 to group_count - index1 ;

      point2 = point_start + index1 + index2;
      set have (keep=pmt) point=point2;

      point3 = point_start + index2 + 1;
      set have (keep=months rename=months=i) point=point3;

      output;
    end;
  end;

  point_end = point1;

  keep cust_id pmt months i;
run;