Sas 扣合数据并仅选择部分扣合值
假设我希望仅对数据值进行校准,其中每个类别中的值的频率大于或等于10。(这简化了我在SAS表中的数据设置方式,同一类别的相同值出现在不同行中是有原因的,在实际数据集中有4个类别和数十万个值观测值) 因此,在上述A类示例中,值-1和0.1将被校准,因为它们的频率分别为13和12,大于或等于10,但-0.5不会。然而,对于B类,应在(频率=11,14)上校准值-0.9和-0.5。不同类别应分别进行校准。 我试图使用SAS在每个类别中只选择频率大于或等于10的值 最好先选择一个值,然后再将其扩展到其他值。如果我将上述数据集称为“分类”数据集,并将我尝试创建的新数据集称为“校准”数据集,那么我得到的结果如下:Sas 扣合数据并仅选择部分扣合值,sas,Sas,假设我希望仅对数据值进行校准,其中每个类别中的值的频率大于或等于10。(这简化了我在SAS表中的数据设置方式,同一类别的相同值出现在不同行中是有原因的,在实际数据集中有4个类别和数十万个值观测值) 因此,在上述A类示例中,值-1和0.1将被校准,因为它们的频率分别为13和12,大于或等于10,但-0.5不会。然而,对于B类,应在(频率=11,14)上校准值-0.9和-0.5。不同类别应分别进行校准。 我试图使用SAS在每个类别中只选择频率大于或等于10的值 最好先选择一个值,然后再将其扩展到其他
data Calibrated;
set Categorised;
if Category="A" and Value= -1 then new = sum(Frequency);
run;
但这只会生成一个名为“new”的额外列,该列在“Categorized”数据集中的值为-1时具有相同的频率条目。如何继续?您可以使用proc-sql执行以下操作
data have;
input
Category $ Value Frequency;
datalines;
A -1 6
A -1 7
A -0.5 4
A 0.1 12
B -1 9
B -0.9 6
B -0.9 5
B -0.5 14
;
proc sql;
create table have_to_calibrate as
select * from have
group by category, value
having sum(frequency)> 10;
您尚未指出在输出中是否希望(a)频率聚合满足条件的所有原始记录,或(b)仅满足条件的唯一(类别、值)对 如果您想要(a),Kiran已经提供的SQL解决方案很好,是我能想到的最简洁的解决方案。但是,如果您希望在数据步骤中使用它,也可以这样做。首先,假设您的数据是按(类别、值)进行排序的,看起来是这样的。然后,您可以编写所谓的双道循环:
data want (drop = _:) ;
do _n_ = 1 by 1 until (last.value) ;
set have ;
by category value ;
_fsum = sum (_fsum, frequency) ;
end ;
do _n_ = 1 to _n_ ;
set have ;
if _fsum > 10 then output ;
end ;
run ;
如果您的数据未排序,可以使用哈希表来实现以下效果:
data want (drop = _:) ;
dcl hash h (ordered:"a") ;
h.definekey ("category", "value") ;
h.definedata ("_fsum") ;
h.definedone () ;
do until (last) ;
set have end = last ;
if h.find() ne 0 then _fsum = frequency ;
else _fsum + frequency ;
h.replace() ;
end ;
do until (0) ;
set have ;
h.find() ;
if _fsum > 10 then output ;
end ;
run ;
如果需要(b),即仅使用不同的(类别、值)对,则SQL(以提供的形式)将不起作用。如果将已排序的输入数据解决方案的代码减少为以下值,则数据步骤将停止:
data want (keep = category value) ;
do until (last.value) ;
set have ;
by category value ;
_fsum = sum (_fsum, frequency) ;
end ;
if _fsum > 10 ;
run ;
对于未排序的数据(哈希方法):
问候,
Paul Dorfman我的数据集似乎太大,无法使用Proc SQL。我可以改用数据步骤吗?对于PROC SQL来说,数十万行不应该是个问题。经过测试,使用SAS UE在1个内核和2GB RAM上运行,在1秒(0.37)内处理了800000行。
data want (keep = category value) ;
do until (last.value) ;
set have ;
by category value ;
_fsum = sum (_fsum, frequency) ;
end ;
if _fsum > 10 ;
run ;
data _null_ ;
dcl hash h (ordered:"a") ;
h.definekey ("category", "value") ;
h.definedata ("category", "value", "_fsum") ;
h.definedone () ;
do until (last) ;
set have end = last ;
if h.find() ne 0 then _fsum = frequency ;
else _fsum + frequency ;
h.replace() ;
end ;
h.output (dataset:"want (where = (_fsum > 10))") ;
stop ;
run ;