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

在SAS中使用循环或嵌套循环搜索数据,sas,Sas,我是SAS的初学者。我有以下问题。给定的是一个大数据集(my_time),我将其导入SAS,如下所示 我想实现以下算法 对于每个帐户,查找一个状态,如果它等于na,则在一年后(在获得状态na后一年)查找相同的合同,并将信息“我的日期”、“状态”和“钱”放在三个新列“新的我的日期”、“新的状态”和“新的钱”,如中所示 我需要excel中类似于countifs的东西。我在SAS中找到了类似的循环,但不是为了查看所有行。 我甚至不知道该找哪个关键词 如果有任何提示,我将不胜感激。一个简单的方法是排

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

我想实现以下算法 对于每个帐户,查找一个状态,如果它等于na,则在一年后(在获得状态na后一年)查找相同的合同,并将信息“我的日期”、“状态”和“钱”放在三个新列“新的我的日期”、“新的状态”和“新的钱”,如中所示

我需要excel中类似于
countifs
的东西。我在SAS中找到了类似的循环,但不是为了查看所有行。 我甚至不知道该找哪个关键词


如果有任何提示,我将不胜感激。

一个简单的方法是排序,然后首先利用特殊变量前缀
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;
对于每一行,我们比较三件事:

  • 状态不是“na”吗
  • 第一年是否比上一次的“na”大
  • 这和我们比较的是同一个账户吗
  • 如果都是真的,那么我们要创建三个新变量

    发生了什么:

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

    由于SAS数据步骤只向前移动,不喜欢向后移动,因此我们希望它记住该帐户第一次出现
    na
    retain
    告诉SAS在读取新行时不要放弃变量的值

    当我们完成比较并转到下一个帐户时,我们将这些变量重置为missing
    by
    group processing允许SAS准确地知道帐户的第一次和最后一次出现在数据集中的位置

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


    最后的语句,
    drop 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;
    
    对于每一行,我们比较三件事:

  • 状态不是“na”吗
  • 第一年是否比上一次的“na”大
  • 这和我们比较的是同一个账户吗
  • 如果都是真的,那么我们要创建三个新变量

    发生了什么:

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

    由于SAS数据步骤只向前移动,不喜欢向后移动,因此我们希望它记住该帐户第一次出现
    na
    retain
    告诉SAS在读取新行时不要放弃变量的值

    当我们完成比较并转到下一个帐户时,我们将这些变量重置为missing
    by
    group processing允许SAS准确地知道帐户的第一次和最后一次出现在数据集中的位置

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


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

    您如何确定它是一年后的时间:当
    提前至少1年,或者
    我的日期
    提前至少12个月?如果一个帐户在其状态变为“na”后13、14和15个月再次出现,该怎么办:您会为每个帐户都写一行吗?数据集是否如此大?dat性能是否是一个问题?如果是,重要的是要知道数据集是否预先排序。@DirkHorsten:1年后表示我的_日期+12个月。这就是我在我的数据中引入我的_日期的原因。这是一个数据集,其中每个帐户每月显示一个状态。我们希望在status='na'数据集排序后12个月检查状态性能不应成为问题如何排序。您提供的数据片段太小了,您如何确定它是一年后的时间:当
    提前至少1年,或者
    我的日期
    提前至少12个月?我