使用SAS

时间:2016-09-08 13:30:30

标签: sas

我是SAS的初学者。我有以下问题。给出了一个大数据集(my_time),我将其导入SAS,如下所示

enter image description here

我想实现以下算法 对于每个帐户查找状态,如果等于 na ,则在一年后(状态 na 后一年)查找相同的合同并将其放入信息“my_date”,“status”和“money”在三个新栏目“new_my_date”,“new_status”和“new_money”中如

enter image description here

我需要像excel中的countifs这样的东西。我在SAS中发现了像DO这样的循环,但并不是为了查看所有行。 我甚至不知道我要看哪个关键词。

我会感激任何提示。

1 个答案:

答案 0 :(得分:5)

一个简单的方法是排序,然后利用特殊变量前缀first.retain语句来获得所需的结果。

第1步:按帐户,日期和状态排序

proc sort data=have;
    by account my_date status;
run;

这可以保证您的数据符合您的需要。因为我们只是在状态='na'之后只查看年份+ 1,所以之间发生的任何事情都无关紧要。

第2步:使用数据步骤记住该帐户na发生的第一年

data want;
    set have;
    by account my_date status;

    retain first_na_year first_na_account;

    if(first.account) then call missing(first_na_year,first_na_account);

    if(status IN('na', 'tna') ) then do;
         first_na_year    = year;
         first_na_month   = month;
         first_na_account = account;
    end;

    if(    year           = first_na_year+1 
       AND first_na_month = month 
       AND account        = first_na_account)  
       AND status NOT IN('na', 'tna') )
    then do;
        new_status  = status ;
        new_my_date = my_date;
        new_money   = money;
    end;

    if(cmiss(new_status, new_my_date, new_money) ) = 0;

    drop first:;
run;

对于每一行,我们比较三件事:

  1. 状态不是'na'?
  2. 第1年比上一次“na”更大吗?
  3. 这是我们正在比较的帐户吗?
  4. 如果一切都是真的,那么我们想要创建三个新变量。

    发生了什么:

    SAS本质上是一种循环语言,因此我们不需要在这里使用do循环。当SAS转到新行时,它将清除程序数据向量(PDV)中的所有变量,以准备使用行中的新值填充它们。

    由于SAS SAS数据步骤只是前进而不想倒退,我们希望它记住第一次为该帐户发生naretain告诉SAS在读取新行时不要丢弃变量的值。

    当我们完成比较并且我们已经转移到下一个帐户时,我们将这些变量重置为缺失。 by组处理允许SAS确切知道帐户的第一次和最后一次出现在数据集中的位置。

    最后,只有在所有3个新变量都没有丢失时才输出。 cmiss计算未丢失的变量数。请注意,output语句之前始终隐含run,因此我们只需要在这种情况下使用“if without then”。

    最终语句drop first:;是一个简单的快捷方式,用于删除以短语first开头的所有变量。这可以防止它们显示在最终数据集中。