使用SAS中的循环或嵌套循环搜索数据

man*_*niA 0 sas

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

在此输入图像描述

我希望为每个帐户查找状态实现以下算法,如果它等于na,则在一年后(在获得状态na后一年)查找相同的合同并将信息"my_date","status" "和"钱"在三个新栏目"new_my_date","new_status"和"new_money"中

在此输入图像描述

我需要像countifsexcel 这样的东西.我发现SAS中的循环就像DO一样, 但不是为了查看所有行.我甚至都不知道我要看哪个关键词.

任何暗示我都会感激不尽.

Stu*_*ski 5

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

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

proc sort data=have;
    by account my_date status;
run;
Run Code Online (Sandbox Code Playgroud)

这样可以保证您的数据符合您的需求.由于我们在status ='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;
Run Code Online (Sandbox Code Playgroud)

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

  1. 状态不是'na'吗?
  2. 比上次'na'年份大1年?
  3. 这是我们正在比较的帐户吗?

如果一切都是真的,那么我们想要创建三个新变量.

发生了什么:

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

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

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

最后,只有在所有3个新变量都没有丢失时才输出.cmiss计算没有丢失多少变量.请注意,outputrun语句之前总是隐含,因此在这种情况下我们只需要使用"if without then".

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