如何在SAS中按类和ID创建运行条件和变量
根据累积的事件计数(如果时间间隔小于10天,则将其视为一个事件),我想根据class by ID计算运行事件计数的“宽”和“长”版本 这就是我现在的数据如何在SAS中按类和ID创建运行条件和变量,sas,Sas,根据累积的事件计数(如果时间间隔小于10天,则将其视为一个事件),我想根据class by ID计算运行事件计数的“宽”和“长”版本 这就是我现在的数据 id Class Date Obsvn Episode_Sum 9 Wide 3/10/2012 1 1 9 Wide 3/12/2012 2 1 9 Wide 7/1/2012 111 2 9 Wide 7/3/2012 2 2 108 Wide 3
id Class Date Obsvn Episode_Sum
9 Wide 3/10/2012 1 1
9 Wide 3/12/2012 2 1
9 Wide 7/1/2012 111 2
9 Wide 7/3/2012 2 2
108 Wide 3/31/2011 1 1
108 Long 3/31/2011 1 1
108 Wide 4/17/2011 17 2
108 Wide 6/24/2011 68 3
108 Wide 6/16/2012 358 4
108 Wide 7/20/2012 34 5
108 Wide 7/27/2012 7 5
我通过以下代码实现了运行计数:
data want (drop=lag); set have;
by id date;
format lag mmddyy10.;
lag=lag(date);
if first.id then obsvn=1;
else obsvn=max(intck("Day", Lag, date),1);
if first.id then episode_sum=1;
else if obsvn>10 then episode_sum+1;
run;
我希望我的数据如下所示:
id Class Date Obsvn Sum Wide Long
9 Wide 3/10/2012 1 1 1 0
9 Wide 3/12/2012 2 1 1 0
9 Wide 7/1/2012 111 2 2 0
9 Wide 7/3/2012 2 2 2 0
108 Wide 3/31/2011 1 1 1 0
108 Long 3/31/2011 1 1 1 1
108 Wide 4/17/2011 17 2 2 1
108 Wide 6/24/2011 68 3 3 1
108 Wide 6/16/2012 358 4 4 1
108 Wide 7/20/2012 34 5 5 1
108 Wide 7/27/2012 7 5 5 1
但我明白了:
id Class Date Obsvn Sum Wide Long
9 Wide 3/10/2012 1 1 1 0
9 Wide 3/12/2012 2 1 1 0
9 Wide 7/1/2012 111 2 2 0
9 Wide 7/3/2012 2 2 **1** 0
108 Wide 3/31/2011 1 1 1 **1**
108 Long 3/31/2011 1 1 1 1
108 Wide 4/17/2011 17 2 2 1
108 Wide 6/24/2011 68 3 3 1
108 Wide 6/16/2012 358 4 4 1
108 Wide 7/20/2012 34 5 5 1
108 Wide 7/27/2012 7 5 **1** 1
这是我的代码,以创建宽和长的插曲。我试图解释每个ID何时切换类。我如何做到这一点
/*Calculating Long*/
if (first.id and class in ("Long")) then Episode_Long=1;
else if obsvn>10 and class in ("Long") then Episode_Long+1;
retain Episode_Long;
if (obsvn<10 and class in ("Long")) then Episode_Long=1;
if class not in ("Long") then do;
if first.id and class not in ("Long") then Episode_Long=0;
retain Episode_Long;
end;
/*Calculating Wide */
if (obsvn<10 and class in ("Wide")) then Episode_Wide=1 ;
if (first.id and class in ("Wide")) then Episode_Wide=1;
else if obsvn>10 and class in ("Wide") then Episode_Wide+1;
retain Episode_Wide;
/*计算长*/
如果(第一个id和“长”中的类),则第1集\u长=1;
否则,如果obsvn>10且课程为(“长”),则第1集为长+1;
保留一段时间;
如果(obsvn棘手的部分是,在第二个ID组中有两条相同日期的记录。因此,在计算以天为单位的变化时,您希望跟踪这一点
这里有一种方法。首先,让我们输入您的源数据(以及所需的结果)
您可能希望首先找到宽间隙或长间隙存在的日期
data long ;
set have ;
by id date;
where class='Long';
if first.date;
lag=lag(date);
if first.id then call missing(lag,obsvn);
else obsvn=max(intck("Day", Lag, date),1);
lflag = missing(lag) or obsvn > 10 ;
keep id date lflag ;
run;
data wide ;
set have ;
by id date;
where class='Wide';
if first.date;
lag=lag(date);
if first.id then call missing(lag,obsvn);
else obsvn=max(intck("Day", Lag, date),1);
wflag = missing(lag) or obsvn > 10 ;
keep id date wflag ;
run;
然后按日期将其合并回源并计算计数器
data want ;
merge have wide long ;
by id date;
if first.date then do ;
lag=lag(date);
format lag yymmdd10.;
if first.id then call missing(lag,obsvn);
else obsvn=max(intck("Day", Lag, date),1);
retain lag obsvn;
end;
if first.id then call missing(sum,wide,long);
if missing(lag) or obsvn > 10 then sum+first.date ;
wide + (wflag and first.date);
long + (lflag and first.date);
run;
您是说要将ID和CLASS作为分组变量吗?您是否尝试在BY语句和您的FIRST.logic中对这两个变量进行排序并使用它们?您好Tom,谢谢您的回答。我正在按ID和日期进行排序。我无法将CLASS变量添加到BY语句中,因为运行总数取决于EPIOde发生。很多时候,一条记录可能从广度开始,然后随着时间的推移切换到长度。我需要考虑这种切换,同时根据日期之间的天数生成正确的集数。我希望这是有意义的。@Jasamack,您是否尝试过使用retain语句?这将允许您在PDV执行期间保持变量的状态…@DanielVieira,您好,是的,我已经尝试了retain语句,这在我上面的示例代码中,但我不确定它的正确位置。您好Tom,谢谢!这段代码似乎让我更接近我的目标,但在切换时(从长到宽,反之亦然)效果不好如果出现一组“长”的观察结果,那么对于一个特定的记录,会出现一个“宽”的观察,当它应该计数发生时,宽变量保持0。听起来你可能需要两个单独的“滞后”。变量。一个代表宽,一个代表长。我更新了它,以在单独的步骤中处理长和宽。现在使用您的messier数据进行尝试。谢谢!这似乎适用于IDs中的所有不同类。我刚刚添加了:如果obsvn=。那么obsvn=1;
到代码末尾。
data want ;
merge have wide long ;
by id date;
if first.date then do ;
lag=lag(date);
format lag yymmdd10.;
if first.id then call missing(lag,obsvn);
else obsvn=max(intck("Day", Lag, date),1);
retain lag obsvn;
end;
if first.id then call missing(sum,wide,long);
if missing(lag) or obsvn > 10 then sum+first.date ;
wide + (wflag and first.date);
long + (lflag and first.date);
run;