假设我希望仅校准数据值,其中每个类别中的值的频率大于或等于10.(这是我在SAS表中列出的数据的简化,有同一类别的相同值出现在不同行中的原因,在实际数据集中有4个类别和数十万个值观察值)
Category Value Frequency
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
因此,在上面的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的频率条目相同。我该怎么办?
答案 0 :(得分:0)
你可以使用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;
答案 1 :(得分:0)
您尚未在输出中指出(a)所有原始记录的频率汇总是否满足您的条件,或者(b)只有符合条件的唯一(类别,值)对。
如果你想要(a),Kiran已经提供的SQL解决方案很好,是我能想到的最简洁的解决方案。但是,你想要它在DATA步骤中,它也可以完成。首先,假设您的数据按照(类别,值)排序,就像它看起来一样。然后你可以编写所谓的双DoW循环代码:
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步骤:
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 ;
此致
保罗多夫曼