Arrays 在SAS中设置阵列中的条件
我有一组数据如下所示:Arrays 在SAS中设置阵列中的条件,arrays,count,sas,Arrays,Count,Sas,我有一组数据如下所示: ID Status31Jan2007 Status28Jan2007 Status31Mar2007 001 0 0 002 1 0 0 003 1 1 0 ID Flag1 Flag2
ID Status31Jan2007 Status28Jan2007 Status31Mar2007
001 0 0
002 1 0 0
003 1 1 0
ID Flag1 Flag2 Flag3
001 N N N
002 Y N N
003 Y Y N
我的Statusddmmyyyy字段为“0”或“1”,持续118个月。(在这里,我只有三个月的时间作为样本)
我希望得到如下结果:
ID Status31Jan2007 Status28Jan2007 Status31Mar2007
001 0 0
002 1 0 0
003 1 1 0
ID Flag1 Flag2 Flag3
001 N N N
002 Y N N
003 Y Y N
逻辑是,如果在Status31Jan2007=1,并且在接下来的两个月内,状态字段计数为0>0,然后将其标记为“Y”。否则,N
意思是,
如果我的ID为001,并且截至2007年1月31日的状态,该值丢失,则我会在Flag1下将其标记为“N”。
接下来的一个月,Status28Feb2007,值为0,我会在Flag2下自动将其标记为“N”。这适用于下个月
查看ID 002,2007年1月31日的状态为1。两个月后,我有两个0值。“0”值的计数大于0。因此,我在Flag1下将其标记为“Y”。
但在2007年2月28日的状态下,它是0。它不符合标准,因此我在Flag2下将其标记为“N”
只要在现场,我需要的状态是1,然后只有我继续研究接下来的两个月
得到结果后,如何计算每个字段下的标志N和Y的数量
Count1 Count2 Count3
N 1 2 3
Y 2 1 0
非常感谢您的帮助,因为我是SAS的新手。谢谢。这只在列名按日历顺序排列时有效 使用
ARRAY
语句按索引组织并访问变量,从而轻松处理[index+1]和[index+2]检查逻辑指示。在分配标志值时,还可以使用临时数组来维护计数;在最后一行,计数被输出到一个单独的表中
注意:对于0或1的状态变量,可以使用SUM
计算1的计数。当两个状态变量中的任何一个为0时,两个状态变量之和将小于2
* simulate some data;
data prelim;
do id = 1 to 20;
do date = '01jan07'd by 1 until(intck('month', '01jan07'd, date) >= 117);
date = intnx('month', date, 1) - 1;
status = ranuni(123) < 0.45;
if date = '31jan07'd and mod(id,5) = 1 then status = .;
output;
end;
end;
format date date9.;
run;
* change the shape of simulated data to match the question;
proc transpose data=prelim prefix=Status out=have(drop=_name_);
by id;
var status;
id date;
run;
* process the problem shaped data;
data
want (keep=id status: flag:)
want_count (keep=flag_value count:);
;
set have end=lastid;
retain sentinel1 sentinel2 0;
array status status: sentinel1 sentinel2; * map all the Status* variables to an array named status;
array flag [118] $1 ; * automatically creates 118 new variables flag1 to flag118;
array yfreq [118] _temporary_ (118*0); * temporary arrays initialized to 0;
array nfreq [118] _temporary_ (118*0);
* process each month status, -2 because of the sentinels ;
do i = 1 to dim(status)-2;
* assign flag according to the logic, some cases require a 2-month look ahead;
select;
when ( status(i) = . ) flag(i) = 'N';
when ( status(i) = 0 ) flag(i) = 'N';
when ( status(i) = 1
and sum(status(i+1),status(i+2)) < 2 ) flag(i) = 'Y'; * SUM trick;
otherwise
flag(i) = 'N';
end;
* track frequencies of flags assigned;
if flag(i) = 'N'
then nfreq(i)+1;
else yfreq(i)+1;
end;
output want;
if lastid then do;
* all flags for all ids have been binned for frequency;
* output the freqs to a count data set;
length flag_value $1;
array freq count1-count118;
flag_value = 'N'; do i = 1 to dim(nfreq); freq(i) = nfreq(i); end; output want_count;
flag_value = 'Y'; do i = 1 to dim(yfreq); freq(i) = yfreq(i); end; output want_count;
end;
run;
*模拟一些数据;
数据预校准;
do id=1至20;
执行日期='07年1月1日,直到(intck('month','07年1月1日,日期)>=117);
日期=intnx('month',date,1)-1;
状态=拉努尼(123)<0.45;
如果日期为'2007年1月31日'd,且日期(id,5)=1,则状态为。;
产出;
结束;
结束;
格式化日期9。;
跑
*改变模拟数据的形状以匹配问题;
proc transpose data=prelim prefix=Status out=have(drop=\u name\uu);
按身份证;
var状态;
身份证日期;
跑
*处理问题型数据;
数据
想要(保留=id状态:标志:)
想要计数(保持=标志值计数:);
;
设置have end=lastid;
保留哨兵1哨兵2 0;
阵列状态:Sentine1 sentinel2;*将所有Status*变量映射到名为Status的数组;
数组标志[118]$1;*自动创建118个新变量flag1到flag118;
数组yfreq[118]u临时_u118*0)*临时数组初始化为0;
数组nfreq[118]\u临时(118*0);
*处理每月状态,-2因为哨兵;
do i=1至变光(状态)-2;
*根据逻辑分配标志,有些情况需要提前2个月;
选择;
当(状态(i)=)标志(i)=‘N’时;
当(状态(i)=0)标志(i)=“N”时;
当(状态(i)=1时
和和(状态(i+1),状态(i+2))<2)标志(i)=‘Y’;*求和技巧;
否则
旗帜(i)=‘N’;
结束;
*跟踪指定旗帜的频率;
如果标志(i)=‘N’
然后nfreq(i)+1;
其他yfreq(i)+1;
结束;
产出需求;
如果是lastid,那么就这样做;
*所有ID的所有标志都已为频率装箱;
*将频率输出到计数数据集;
长度标志_值$1;
数组频率count1-count118;
标志_值='N';do i=1至dim(nfreq);频率(i)=nfreq(i);结束;输出要计数;
标志_值='Y';do i=1至dim(yfreq);频率(i)=yfreq(i);结束;输出要计数;
结束;
跑
我对逻辑有点不清楚,您希望每列的值是否取决于接下来两列中的值,如果是这种情况,那么最后两列将如何计算。也许可以解释一下您所显示的想要的值是如何计算的,例如,为什么在第一次观察中Flag1
=N等等。我已经做了进一步的解释。希望它更清楚!:)第一列的值取决于以下两列的值。第二列将取决于接下来的两列,依此类推。谢谢。因此,据我所知,如果当前列为1
,您只需要查看下两列。两个问题:(1)最后两列的逻辑是什么,因为你不能向前看两列?(2) 列名是否有模式?如果有,那么模式是什么?为了回答您的问题,(1)对于第二列,我将看最后一列。在最后一篇专栏文章中,我希望我的结果被标记为“N”,因为我不能再向前看了。(2) 对于我当前的数据集,我的列名仅为Status31Jan2007-Status31Oct2016。如果方便的话,我可以将其重命名为Status1-Status118。对于我的输出,它将使用不同的名称,所以可能是Flag1-Flag118。这就是你说的模式吗?