如何选择组内最常见的值(不是只有一个)

时间:2015-11-18 19:05:26

标签: sas

我有一个数据集,其中包含一个分组字符变量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

4 个答案:

答案 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 xn=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;