SAS中的多do循环

SAS中的多do循环,sas,iteration,do-loops,Sas,Iteration,Do Loops,我有一个2017年至2018年每周收入百分比的数据集。一些公司在2017年初没有数据,因为他们直到后来才开始盈利。周数分别为201701、201702-201752和201801-201852 我想做的是有104个新变量,称为WEEK0-WEEK103,其中WEEK0将有挣钱列的第一个非空列值。以下是数据示例: MON_EARN_201701 MON_EARN_201702 MON_EARN_201703 MON_EARN_201704 30

我有一个2017年至2018年每周收入百分比的数据集。一些公司在2017年初没有数据,因为他们直到后来才开始盈利。周数分别为201701、201702-201752和201801-201852

我想做的是有104个新变量,称为WEEK0-WEEK103,其中WEEK0将有挣钱列的第一个非空列值。以下是数据示例:

MON_EARN_201701      MON_EARN_201702      MON_EARN_201703    MON_EARN_201704
     30                     21                  50                 65   
     .                       .                  30                 100   
     .                      102                 95                 85    
然后,我希望我的数据具有以下列(示例)

这些只是一个非常大的数据集的小例子

我在想我需要尝试做一些do循环,所以到目前为止我尝试的是:

DATA want;
SET have;
ARRAY mon_earn{104} mon_earn_201701 - mon_earn_201752 mon_earn_201801 -mon_earn_201852;
ARRAY WEEK {104} WEEK0 - WEEK103;
DO i = 1 to 104;
IF mon_earn{i} NE . THEN;
WEEK{i} = mon_earn{i};
END;
END;
RUN;
这不起作用,因为当第一个值为空时,它不会填充周末0


如果需要更多信息,请发表评论,我会将其添加进来

如果是长格式,您可以这样做。在长格式中,您可能不需要它

proc sort data=have;
by ID week;
run;

data want;
set have;
by id; *for each group/id counter;
retain counter;
if first.id then counter=0; 
if counter=0 and not missing(value) then do;
counter=1; new_week=0; end;
if counter = 1 then new_week+1;
run;
如果您确实需要广泛使用:

  • 查找第一个不丢失的值并在i中存储索引
  • 循环从i到周末维度
  • 将一周分配给从i到周末的mon_

    data want;
        set have;
        array mon_earned(*) .... ;
        array week(*) ... ;
        found=0; i=0;
    
        do while(found=0);
           if not missing(mon_earned(i)) then found=1;
           i+1;
        end;
    
        z=0;
        do j=i to dim(week);
            week(z) = mon_earned(j); 
            z+1;
        end;
    run;
    

  • 如果是长格式,您可以这样做。在长格式中,您可能不需要它

    proc sort data=have;
    by ID week;
    run;
    
    data want;
    set have;
    by id; *for each group/id counter;
    retain counter;
    if first.id then counter=0; 
    if counter=0 and not missing(value) then do;
    counter=1; new_week=0; end;
    if counter = 1 then new_week+1;
    run;
    
    如果您确实需要广泛使用:

  • 查找第一个不丢失的值并在i中存储索引
  • 循环从i到周末维度
  • 将一周分配给从i到周末的mon_

    data want;
        set have;
        array mon_earned(*) .... ;
        array week(*) ... ;
        found=0; i=0;
    
        do while(found=0);
           if not missing(mon_earned(i)) then found=1;
           i+1;
        end;
    
        z=0;
        do j=i to dim(week);
            week(z) = mon_earned(j); 
            z+1;
        end;
    run;
    

  • 您需要第二个索引变量,称之为
    j
    ,以正确的周分配为目标
    j
    仅在不缺少月收入时递增

    此示例代码将“挤出”所有缺失的收入;即使是那些在某些收益发生后出现的缺失收益。比如说

    收入:
    。10 . 120 . 25…
    将压缩到
    周:
    1012025…

    data have;
      array earn earn_201701-earn_201752 earn_201801-earn_201852;
      do _n_ = 1 to 1000;
         call missing (of earn(*));
         do _i_ = 1 + 25 * ranuni(123) to dim(earn);
           if ranuni(123) < 0.95 then
             earn(_i_) = round(10 + 125 * ranuni(123));
         end;
         output;
      end;
    run;
    
    data want;
      set have;
      array earn earn_201701-earn_201752 earn_201801-earn_201852;
      array week(0:103);
    
      j = -1;
      do i = 1 to dim(earn);
        if not missing(earn(i)) then do;
          j+1;
          week(j) = earn(i);
        end;
      end;
    
      drop i j;
    run;
    

    您需要第二个索引变量,称之为
    j
    ,以正确的周分配为目标
    j
    仅在不缺少月收入时递增

    此示例代码将“挤出”所有缺失的收入;即使是那些在某些收益发生后出现的缺失收益。比如说

    收入:
    。10 . 120 . 25…
    将压缩到
    周:
    1012025…

    data have;
      array earn earn_201701-earn_201752 earn_201801-earn_201852;
      do _n_ = 1 to 1000;
         call missing (of earn(*));
         do _i_ = 1 + 25 * ranuni(123) to dim(earn);
           if ranuni(123) < 0.95 then
             earn(_i_) = round(10 + 125 * ranuni(123));
         end;
         output;
      end;
    run;
    
    data want;
      set have;
      array earn earn_201701-earn_201752 earn_201801-earn_201852;
      array week(0:103);
    
      j = -1;
      do i = 1 to dim(earn);
        if not missing(earn(i)) then do;
          j+1;
          week(j) = earn(i);
        end;
      end;
    
      drop i j;
    run;
    

    听起来你只需要找到复制的起点

    首先按日历月查看收入列表,直到找到第一个未丢失的值。然后将从那里开始的值复制到相对月份的新收益数组中

    data want;
      set have;
      array mon_earn mon_earn_201701 -- mon_earn_201852;
      array week (104);
      do i = 1 to dim(mon_earn) until(found);
        if mon_earn{i} ne . then found=1;
      end;
      do j=1 to dim(week) while (i+j<dim(mon_earn));
        week(j) = mon_earn(i+j-1);
      end;
    run;
    
    需要数据;
    集有;
    数组mon_earn mon_earn_201701——mon_earn_201852;
    阵列周(104);
    i=1时变暗(mon_earn)直到(found);
    如果你赚了{i}ne。然后发现=1;
    结束;
    
    当(i+j听起来你只需要找到复制的起点时,就可以将j=1变暗(一周)

    首先按日历月查看收入列表,直到找到第一个未丢失的值。然后从那里开始将值复制到按相对月列出的新收入数组中

    data want;
      set have;
      array mon_earn mon_earn_201701 -- mon_earn_201852;
      array week (104);
      do i = 1 to dim(mon_earn) until(found);
        if mon_earn{i} ne . then found=1;
      end;
      do j=1 to dim(week) while (i+j<dim(mon_earn));
        week(j) = mon_earn(i+j-1);
      end;
    run;
    
    需要数据;
    集有;
    数组mon_earn mon_earn_201701——mon_earn_201852;
    阵列周(104);
    i=1时变暗(mon_earn)直到(found);
    如果mon_earn{i}ne.则find=1;
    结束;
    

    j=1时是否变暗(周)(i+j将您的数据转换为长格式,这将非常容易。如果是长格式,我将如何做?您可以排序,您可以从第一个不缺失值开始重新编号。您能否通过回答问题向我展示?我不明白如何重新编号整个数据集,因为每行的第一个不缺失值都是相同的不同的一周,我有100000多行。将您的数据切换到长格式,这将非常容易。如果数据是长格式,我将如何做?您可以排序,您可以从第一个不缺失的值开始重新编号。您能通过回答问题向我展示吗?我不知道如何在每个r时重新编号整个数据集ow的第一个非缺失值位于不同的一周,我有100000多行。感谢您的回答。我确实收到了错误“错误:数组下标0超出了第343行第16列中获得的数组mon_的维度1的范围[1-104]”。我假设我需要在数组中输入变量名,即mon_earn_201701-mon_earn_201752 mon_earn_201801-mon_earn_201852用于第一个数组?谢谢回答。我确实收到错误“错误:数组mon_earn的维度1在第343行第16列的数组下标0超出范围[1-104]”。我假设我需要在数组中输入我的变量名,即mon_earn_201701-mon_earn_201752 mon_earn_201801-mon_earn_201852作为第一个数组?谢谢你,这很有效。我将能够使用此方法处理我遇到的其他问题,再次感谢。如果这是一个愚蠢的问题,很抱歉,但我正在努力完全理解这是可行的,你能给我发个消息解释一下吗?什么是令人困惑的?有两个数组语句。阅读文档中的这些语句是如何工作的。有两个DO循环。再次阅读它们是如何工作的。SAS DO循环非常强大,因为你可以像这样将迭代循环与WHILE或UNTIL边界测试结合起来。TA中的索引RGET数组从1开始,当源数组中的项用完时停止。FOUND是一个缺失或1的数字变量。SAS将把非缺失值和非零值视为TRUE。因此循环将一直运行,直到找到第一个非缺失值。数组索引是整数。I、J和负1是整数。它们的总和为r整数,用作数组的索引。由于J从1变为…并且I是第一个值的位置,因此I+J-1是要复制的当前值的位置。请注意,您不需要使用goofy括号
    []
    {}
    新文档用于数据步骤代码中的数组。普通括号工作正常。我发现