如果变量在第一个实例中匹配 'n' 次未排序数据,则 SAS 分配二进制值
SAS assigning binary values if variable matches in first instance for 'n' times for unsorted data
希望你们都好。
DATA: 输入数据未排序,因此我使用散列 tables 来获取输入数据,进行一些迭代,排序然后输出。在任何迭代(使用 proc 排序)之前对原始 table 进行排序将是一项耗时的工作。如果没有其他选择,那么我将需要坐下来接受可怕的排序方法。
我想要的:我正在尝试枚举一个 table 变量 "answer" 与二进制值 (0/1) 如果变量 filter = "Y" 接下来 6 个月的观察同一个客户。在某些情况下,客户在某些月度观察中缺失,例如:客户 FG5151 在 2006 年 9 月和 10 月缺失。简而言之,如果变量过滤器 "Y",则应为同一客户的此观察和接下来 6 个月的观察分配变量"answer" 当量 1,否则 0。
data have;
input client $ dates date9. filter $;
datalines ;
Fg5151 28.Feb.06 N
Fg5151 31.Mar.06 N
Fg5151 30.Apr.06 N
Fg5151 31.May.06 Y
Fg5151 30.Jun.06 N
Fg5151 31.Jul.06 Y
Fg5151 31.Aug.06 N
Fg5151 30.Nov.06 N
Fg5151 31.Dec.06 N
Fg5151 01.Jan.07 N
A101 28.Feb.06 N
A101 31.Mar.06 N
A101 30.Apr.06 Y
A101 31.May.06 N
A101 30.Jun.06 N
A101 31.Jul.06 N
ABC123 31.Mar.06 N
;
data want;
input client $ dates date9. filter $ answer;
datalines ;
A101 28.Feb.06 N 0
A101 31.Mar.06 N 0
A101 30.Apr.06 Y 1
A101 31.May.06 N 1
A101 30.Jun.06 N 1
A101 31.Jul.06 N 1
ABC123 31.Mar.06 N 0
Fg5151 28.Feb.06 N 0
Fg5151 31.Mar.06 N 0
Fg5151 30.Apr.06 N 0
Fg5151 31.May.06 Y 1
Fg5151 30.Jun.06 N 1
Fg5151 31.Jul.06 Y 1
Fg5151 31.Aug.06 N 1
Fg5151 30.Nov.06 N 1
Fg5151 31.Dec.06 N 1
Fg5151 01.Jan.07 N 0
;
我已经写了哈希语句和数据步骤语句。我不知道如何解决这个问题:
/* data step approach */
data want;
set have;
retain answer c;
if _n_=1 or lag(client) ne client then do;
answer=0;
c=0;
end;
if filter="Y" then do;
call symput('xdate',dates);
answer=1;
c=1;
end;
else if answer=1 then c=c+1;
if (intnx("month",dates,6,"same")) then do;
answer=0;
c=0;
end;
run;
/* hash method approach */
data _null_;
set have end=last;
if _n_ = 1 then do;
length newdate 8 answer 8 c 8;
format newdate ddmmyy10.;
declare hash hs(ordered: "a",hashexp: 9);
hs.defineKey("client","dates");
hs.defineData("client","dates","filter","answer","c");
hs.defineDone();
end;
rc = hs.find();
by client dates notsorted;
if rc ne 0 then do;
retain answer c;
if _n_=1 or lag(client) ne client then do;
answer=0;
c=0;
end;
if filter="Y" then do;
answer=1;
c=1;
hs.add();
end;
else if answer=1 then c=c+1;
if (intnx("month",dates,6,"same")) then do;
answer=0;
c=0;
hs.replace();
end;
hs.replace();
end;
if last eq 1 then do;
hs.output(dataset:
"not_working");
end;
run;
如有任何帮助,我们将不胜感激。
谢谢你。
问候,
S
一个选项是PROC FORMAT
。这里面有一个排序,但只有 filter='Y' 的人,所以希望这是最小的;如果您确信您的数据已按客户端分组(但未排序)(即,您可以跳过它,它不会删除任何内容),并且实际上无论如何都使用 m
选项(以避免担心碰撞)你可能可以跳过它。
这不一定是超快的,因为它使用 putn
函数而不是 put
语句。您将不得不了解它在更大的数据集上的表现。
这里的想法是我们构建一个格式,为每个记录定义 'Y' 的范围,并使用 hlo='o'
选项将剩余的 ragne 定义为 n
。
data for_fmt;
set have;
by client notsorted;
if filter='Y' then do;
start = dates;
end = intnx('Month',dates,5,'s');
hlo=' m';
fmtname=cats(client,'F');
label='Y';
output;
end;
if last.client then do;
fmtname=cats(client,'F');
call missing(of start end);
hlo='om';
label='N';
output;
end;
run;
proc sort nodupkey data=for_fmt;
by fmtname start;
run;
proc format cntlin=for_fmt;
quit;
data want;
set have;
answer = putn(dates,cats(client,'F'));
run;
希望你们都好。 DATA: 输入数据未排序,因此我使用散列 tables 来获取输入数据,进行一些迭代,排序然后输出。在任何迭代(使用 proc 排序)之前对原始 table 进行排序将是一项耗时的工作。如果没有其他选择,那么我将需要坐下来接受可怕的排序方法。
我想要的:我正在尝试枚举一个 table 变量 "answer" 与二进制值 (0/1) 如果变量 filter = "Y" 接下来 6 个月的观察同一个客户。在某些情况下,客户在某些月度观察中缺失,例如:客户 FG5151 在 2006 年 9 月和 10 月缺失。简而言之,如果变量过滤器 "Y",则应为同一客户的此观察和接下来 6 个月的观察分配变量"answer" 当量 1,否则 0。
data have;
input client $ dates date9. filter $;
datalines ;
Fg5151 28.Feb.06 N
Fg5151 31.Mar.06 N
Fg5151 30.Apr.06 N
Fg5151 31.May.06 Y
Fg5151 30.Jun.06 N
Fg5151 31.Jul.06 Y
Fg5151 31.Aug.06 N
Fg5151 30.Nov.06 N
Fg5151 31.Dec.06 N
Fg5151 01.Jan.07 N
A101 28.Feb.06 N
A101 31.Mar.06 N
A101 30.Apr.06 Y
A101 31.May.06 N
A101 30.Jun.06 N
A101 31.Jul.06 N
ABC123 31.Mar.06 N
;
data want;
input client $ dates date9. filter $ answer;
datalines ;
A101 28.Feb.06 N 0
A101 31.Mar.06 N 0
A101 30.Apr.06 Y 1
A101 31.May.06 N 1
A101 30.Jun.06 N 1
A101 31.Jul.06 N 1
ABC123 31.Mar.06 N 0
Fg5151 28.Feb.06 N 0
Fg5151 31.Mar.06 N 0
Fg5151 30.Apr.06 N 0
Fg5151 31.May.06 Y 1
Fg5151 30.Jun.06 N 1
Fg5151 31.Jul.06 Y 1
Fg5151 31.Aug.06 N 1
Fg5151 30.Nov.06 N 1
Fg5151 31.Dec.06 N 1
Fg5151 01.Jan.07 N 0
;
我已经写了哈希语句和数据步骤语句。我不知道如何解决这个问题:
/* data step approach */
data want;
set have;
retain answer c;
if _n_=1 or lag(client) ne client then do;
answer=0;
c=0;
end;
if filter="Y" then do;
call symput('xdate',dates);
answer=1;
c=1;
end;
else if answer=1 then c=c+1;
if (intnx("month",dates,6,"same")) then do;
answer=0;
c=0;
end;
run;
/* hash method approach */
data _null_;
set have end=last;
if _n_ = 1 then do;
length newdate 8 answer 8 c 8;
format newdate ddmmyy10.;
declare hash hs(ordered: "a",hashexp: 9);
hs.defineKey("client","dates");
hs.defineData("client","dates","filter","answer","c");
hs.defineDone();
end;
rc = hs.find();
by client dates notsorted;
if rc ne 0 then do;
retain answer c;
if _n_=1 or lag(client) ne client then do;
answer=0;
c=0;
end;
if filter="Y" then do;
answer=1;
c=1;
hs.add();
end;
else if answer=1 then c=c+1;
if (intnx("month",dates,6,"same")) then do;
answer=0;
c=0;
hs.replace();
end;
hs.replace();
end;
if last eq 1 then do;
hs.output(dataset:
"not_working");
end;
run;
如有任何帮助,我们将不胜感激。 谢谢你。 问候, S
一个选项是PROC FORMAT
。这里面有一个排序,但只有 filter='Y' 的人,所以希望这是最小的;如果您确信您的数据已按客户端分组(但未排序)(即,您可以跳过它,它不会删除任何内容),并且实际上无论如何都使用 m
选项(以避免担心碰撞)你可能可以跳过它。
这不一定是超快的,因为它使用 putn
函数而不是 put
语句。您将不得不了解它在更大的数据集上的表现。
这里的想法是我们构建一个格式,为每个记录定义 'Y' 的范围,并使用 hlo='o'
选项将剩余的 ragne 定义为 n
。
data for_fmt;
set have;
by client notsorted;
if filter='Y' then do;
start = dates;
end = intnx('Month',dates,5,'s');
hlo=' m';
fmtname=cats(client,'F');
label='Y';
output;
end;
if last.client then do;
fmtname=cats(client,'F');
call missing(of start end);
hlo='om';
label='N';
output;
end;
run;
proc sort nodupkey data=for_fmt;
by fmtname start;
run;
proc format cntlin=for_fmt;
quit;
data want;
set have;
answer = putn(dates,cats(client,'F'));
run;