Sas 扣合数据并仅选择部分扣合值

Sas 扣合数据并仅选择部分扣合值,sas,Sas,假设我希望仅对数据值进行校准,其中每个类别中的值的频率大于或等于10。(这简化了我在SAS表中的数据设置方式,同一类别的相同值出现在不同行中是有原因的,在实际数据集中有4个类别和数十万个值观测值) 因此,在上述A类示例中,值-1和0.1将被校准,因为它们的频率分别为13和12,大于或等于10,但-0.5不会。然而,对于B类,应在(频率=11,14)上校准值-0.9和-0.5。不同类别应分别进行校准。 我试图使用SAS在每个类别中只选择频率大于或等于10的值 最好先选择一个值,然后再将其扩展到其他

假设我希望仅对数据值进行校准,其中每个类别中的值的频率大于或等于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 ;