使用分组处理首先。和最后

时间:2017-06-28 21:35:27

标签: sas

我刚开始学习sas,希望能帮助理解下面的代码块。以下程序按部门计算年度工资单。

proc sort data = company.usa out=work.temp;
   by dept;
   run;
data company.budget(keep=dept payroll);
    set  work.temp;
    by dept;
    if wagecat ='S' then yearly = wagrate *12;
    else if wagecat = 'H' then yearly = wagerate *2000;
    if first.dept then payroll=0;
    payroll+yearly;
    if last.dept;

    run;

问题:

  1. out = work.temp在这段代码的第一行做了什么?
  2. 我理解数据步骤为每个变量创建了2个临时变量(first.varibale / last.variable),值为1或0,但是first.dept和last.dept在代码中完全做了什么?
  3. 为什么在第二行到最后一行的first.dept后需要payroll = 0?

1 个答案:

答案 0 :(得分:1)

此代码获取工资数据并计算每个部门一年的工资额,假设所有12个月的工资相同,并且每小时工人工作2000小时。

  1. 它创建数据集的副本,该副本被排序并存储在工作库中。 RTM。
  2. From the docs

      

    OUT = SAS数据集   命名输出数据集。如果SAS数据集不存在,则PROC SORT创建它。   的注意:   在没有OUT =的情况下使用PROC SORT时要小心。   如果没有OUT =选项,PROC SORT会在程序执行时没有错误地将原始数据集替换为已排序的观察值。   默认情况下没有OUT =,PROC SORT会覆盖原始数据集。   提示对于数据库内排序,输出数据集不能引用DBMS上的输入表。   您可以使用OUT =的数据集选项。   请参阅SAS数据集选项:参考   示例按多个变量的值排序

    1. First.DEPT是一个指示变量,表示对特定BY组的第一次观察。因此,当您遇到某个部门的第一个记录时,它就会被识别出来。 Last.DEPT是该特定部门的最后一条记录。这意味着下一条记录将成为不同部门的第一条记录。

    2. 在每条记录的第一条中将PAYROLL设置为0。由于您有if last.dept;,这意味着只输出每个部门的最后一条记录。这段代码不直观 - 这是一种手工方式来计算每个部门人员的工资。常见的方法是使用摘要程序,例如MEANS / SUMMARY,但我认为他们试图避免两次传递数据。虽然如果你没有排序,反正可能同样快。

    3. Again, RTM here。 SAS文档对这些初学者主题非常详尽。

      这是一种替代方法,应该生成完全相同的结果,但更直观的IMO。

      data temp;
        set company.usa;
        if wagecat='S' then factor=12; *salary in months;
        else if wagecat='H' then factor=2000; *salary in hours;
      run;
      
      proc means data=temp noprint NWAY;
      class dept;
      var wagerate;
      weight factor;
      output out=company.budget sum(wagerate)=payroll;
      run;