sas:根据日期统计行数
我正在处理犯罪数据。现在,我有下表sas:根据日期统计行数,sas,Sas,我正在处理犯罪数据。现在,我有下表犯罪。每行包含一个特定的犯罪(例如袭击):犯罪日期(日期)和罪犯的个人ID(个人) 我感兴趣的是,在同一个人犯下第一次罪行后的1年内,每个人是否犯下(复发=1)或没有犯下(复发=0)另一次罪行。另一个条件是第一次犯罪必须在特定年份内发生(此处为2017年) 因此,结果应如下所示: date person relapse ------------------------------ 02JAN2017 1 1
犯罪
。每行包含一个特定的犯罪(例如袭击):犯罪日期(日期
)和罪犯的个人ID(个人
)
我感兴趣的是,在同一个人犯下第一次罪行后的1年内,每个人是否犯下(复发=1)或没有犯下(复发=0)另一次罪行。另一个条件是第一次犯罪必须在特定年份内发生(此处为2017年) 因此,结果应如下所示:
date person relapse
------------------------------
02JAN2017 1 1
03FEB2017 1 1
04JAN2018 1 1
27NOV2017 2 0
28NOV2018 2 0
01MAY2017 3 1
24FEB2018 3 1
10OCT2017 4 0
谁能告诉我如何在SAS中实现这一点?
很明显,实际数据要大得多,所以我无法手动操作。一种方法是使用数据逐步分组处理
BY
语句设置二进制变量first.
和last.
标记组中的第一行和组中的最后一行
您似乎正在为整个组分配computed Recurse标志,这种计算可以通过SAS编码人员称之为DOW循环的方式完成——循环中包含SET
语句的循环,以及将计算分配给组中每一行的后续循环
INTCK
函数可以计算两个日期之间的年数
例如:
data want(keep=person date relapse);
* DOW loop computes assertion that relapse occurred;
relapse = 0;
do _n_ = 1 by 1 until (last.person);
set crimes; * <-------------- CRIMES;
by person date;
* check if persons first crime was in 2017;
if _n_ = 1 and year(date) = 2017 then _first = date;
* check if persons second crime was within 1 year of first;
if _n_ = 2 and _first then relapse = intck('year', _first, date, 'C') < 1;
end;
* at this point the relapse flag has been computed, and its value
* will be repeated for each row output;
* serial loop over same number of rows in the group, but
* read in through a second SET statement;
do _n_ = 1 to _n_;
set crimes; * <-------------- CRIMES;
output;
end;
run;
所需数据(keep=person-date-recurse);
*DOW loop计算复发发生的断言;
复发率=0;
1乘1直到(最后一人);
设定罪行;* 我是最近才开始使用sas的——我并没有试图在这里创建完美的代码
我会先按id/人和日期对数据进行排序(日期应该是数字),然后使用retain语句检查第一次犯罪的日期。它不是完美的,但如果你的数据是好的(没有遗漏日期),它会工作,并且很容易遵循imho
只有在2017年出现第一次犯罪记录和行为的情况下,这才有效。如果您在2016年发生了犯罪,并且希望检查2017年是否发生了“犯罪”,然后检查复发,那么此代码将不起作用-但我认为您的问题下面的评论中包含了这一点
data test;
input tmp_year $ 1-9 person;
datalines;
02JAN2017 1
03FEB2017 1
04JAN2018 1
27NOV2017 2
28NOV2018 2
01MAY2017 3
24FEB2018 3
10OCT2017 4
;
run;
data test2;
set test;
crime_date = input(tmp_year, date9.);
act_year = year(crime_date);
run;
proc sort data=test2;
by person crime_date ;
run;
data want;
set test2;
by person crime_date;
retain date_of_crime;
if first.person and act_year = 2017 then date_of_crime = crime_date;
else if first.person then call missing(date_of_crime);
if intck('YEAR', date_of_crime, crime_date) =< 1 and not first.person
then relapse = 1;
else relapse = 0;
run;
数据测试;
输入tmp_年$1-9人;
数据线;
2017年1月2日1
2017年2月3日1
2018年1月4日1
2017年11月27日2
2018年11月28日2
2017年5月1日3
2018年2月24日3
2017年10月10日4
;
跑
数据测试2;
集合测试;
犯罪日期=输入(tmp年,日期9);
行为年=年(犯罪日期);
跑
proc sort data=test2;
按个人犯罪日期;
跑
数据需求;
设置test2;
按个人犯罪日期;
保留犯罪日期;
如果第一人称和行为年=2017年,则犯罪日期=犯罪日期;
否则,如果第一个人打电话失踪(犯罪日期);
如果intck(‘年份’、犯罪日期、犯罪日期)=<1且不是第一人称
然后复发=1;
else复发率=0;
跑
上述代码标记了2017年犯罪行为一年后的犯罪行为。然后,您可以使用proc sql语句检索唯一的人员,并将他们与您拥有的任何数据集连接起来 如果有人在2017年1月、2018年2月和2018年3月犯罪怎么办?(请在问题中填写您的示例)那么,由于2018年2月和2018年3月发生的犯罪在2017年1月之后超过一年,因此不会再次发生。但是,如果这段时间是5年而不是1年,那么他们将被视为复发。如果有人在2016年1月、2017年2月和2017年3月犯罪怎么办?另一个条件是第一次犯罪必须在特定的一年内发生(这里是2017年)。
data test;
input tmp_year $ 1-9 person;
datalines;
02JAN2017 1
03FEB2017 1
04JAN2018 1
27NOV2017 2
28NOV2018 2
01MAY2017 3
24FEB2018 3
10OCT2017 4
;
run;
data test2;
set test;
crime_date = input(tmp_year, date9.);
act_year = year(crime_date);
run;
proc sort data=test2;
by person crime_date ;
run;
data want;
set test2;
by person crime_date;
retain date_of_crime;
if first.person and act_year = 2017 then date_of_crime = crime_date;
else if first.person then call missing(date_of_crime);
if intck('YEAR', date_of_crime, crime_date) =< 1 and not first.person
then relapse = 1;
else relapse = 0;
run;