我有一个数据集,其中包含一个分组字符变量x和一个数字变量y。对于x的每个值,我想选择最多出现的y的值,但是对于x的每个值,我只想要一个y值(无论哪一个)。我知道如何为每个x选择所有这样的y,但我不知道如何只选择一个。
proc sql;
select x,y
from (select x, y, count(*) as n_y
from lab7.a
group by x,y)
group by x
having n_y=max(n_y)
;
quit;
上面的代码为每个x提供了所有这样的y,但我希望每个x只有一个y。
我尝试在子查询中使用n_y的顺序,然后选择前1,但显然它在sas中不起作用。我也试过单调,但是它为整个查询添加了行数,它在组内不起作用。
例如,如果我有数据:
x y
A 1
A 2
A 2
B 1
B 2
C 3
C 3
我的代码将返回
x y
A 2
B 1
B 2
C 3
但我想
x y
A 2
B 1
C 3
或
x y
A 2
B 2
C 3
答案 0 :(得分:3)
由于SAS不支持窗口函数或TOP X,因此我不认为它在单个查询中在技术上可行。您可以将MONOTONIC()与外部查询结合使用,但是:
select x,y from (
select x,y, monotonic() as m
from (select x, y, count(*) as n_y
from have
group by x,y)
group by x
having n_y=max(n_y)
)
group by x
having m=max(m)
;
或者
proc sql;
select x,max(y) from (
select x,y
from (select x, y, count(*) as n_y
from have
group by x,y)
group by x
having n_y=max(n_y)
)
group by x
;
quit;
这当然会给你带来偏见的结果 - 如果你对此感到满意,那就没关系了。
如果你不是,我会做的是把那个有两个的SQL输出,然后用PROC SURVEYSELECT
随机选择一个(strata x
和n=1
)
答案 1 :(得分:2)
更好的非SQL方法是使用PROC UNIVARIATE
。这里唯一的限制是,如果每个值都是一种模式,它似乎不起作用(即,在你的初始例子中,B只有2个值,两者都是模式)。但只要你有足够的价值使这个问题有意义,这应该有用。
proc univariate data=have;
by x;
var y;
output out=want mode=mode_y;
run;
它为您提供了模式,并且可能比SQL
查询快得多。它确实需要按x
进行排序,但是,如果它还没有排序。它默认为您提供最低模式。
答案 2 :(得分:1)
为什么要使用PROC SQL
?
proc freq data=have ;
tables x*y / noprint out=counts ;
run;
proc sort data=counts;
by x descending count;
run;
data want ;
set counts ;
by x ;
if first.x ;
run;
答案 3 :(得分:0)
为什么不:
proc sql;
select x,max(y) from table group by x;
quit;