在SAS中使用循环或嵌套循环搜索数据
我是SAS的初学者。我有以下问题。给定的是一个大数据集(my_time),我将其导入SAS,如下所示 我想实现以下算法 对于每个帐户,查找一个状态,如果它等于na,则在一年后(在获得状态na后一年)查找相同的合同,并将信息“我的日期”、“状态”和“钱”放在三个新列“新的我的日期”、“新的状态”和“新的钱”,如中所示 我需要excel中类似于在SAS中使用循环或嵌套循环搜索数据,sas,Sas,我是SAS的初学者。我有以下问题。给定的是一个大数据集(my_time),我将其导入SAS,如下所示 我想实现以下算法 对于每个帐户,查找一个状态,如果它等于na,则在一年后(在获得状态na后一年)查找相同的合同,并将信息“我的日期”、“状态”和“钱”放在三个新列“新的我的日期”、“新的状态”和“新的钱”,如中所示 我需要excel中类似于countifs的东西。我在SAS中找到了类似的循环,但不是为了查看所有行。 我甚至不知道该找哪个关键词 如果有任何提示,我将不胜感激。一个简单的方法是排
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;
对于每一行,我们比较三件事:
do
循环。当SAS转到新行时,它将清除程序数据向量(PDV)中的所有变量,以准备用行中的新值填充它们
由于SAS数据步骤只向前移动,不喜欢向后移动,因此我们希望它记住该帐户第一次出现na
retain
告诉SAS在读取新行时不要放弃变量的值
当我们完成比较并转到下一个帐户时,我们将这些变量重置为missingby
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在读取新行时不要放弃变量的值
当我们完成比较并转到下一个帐户时,我们将这些变量重置为missingby
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个月?我