1

特定の変数リストのモードを取得しようとしています。モードが一意でない場合、モードを取得するためのサブクエリが (より大きなクエリで) 2 つの値を返さないように、モードの平均を返したいと考えています。ただし、モードが一意の場合、平均クエリは何らかの理由で欠損値を返します。

次のサンプルデータがあります。

data have;
input betprice;
datalines; 
    1.05
    1.05
    1.05
    6
    run;
    PROC PRINT; RUN;

proc sql;
select avg(betprice) 
    from
    (select betprice, count(*) as count_betprice from have group by betprice) 
    having count_betprice = max(count_betprice);
quit;

モードが一意にならないように betprice フィールドにさらにいくつかの観測値を追加すると、平均値が返されます。

data have;
input betprice;
datalines; 
    1.05
    1.05
    1.05
    6
    6
    6

run;
PROC PRINT; RUN;

最も頻度の高い 2 つの値のモードまたは平均が常に返されるように、このクエリを変更するにはどうすればよいですか。

これについて助けてくれてありがとう。

4

3 に答える 3

2

まず、外側のクエリに group by ステートメントがなく、having 句を使用していることに注意してください。これは大丈夫ではありません。

これが機能する解決策です:

proc sql;
    create view WORK.V_BETPRICE_FREQ as
    select betprice, count(*) as count_betprice
    from HAVE
    group by betprice
    ;

    select avg(betprice) as final_betprice
    from WORK.V_BETPRICE_FREQ
    where count_betprice = (select max(count_betprice) from WORK.V_BETPRICE_FREQ)
    ;
quit;

ここでは、コードの重複を防ぐためにビューを使用しました。ビュー内のクエリが CPU に関して非常に負荷の高い操作である場合は、代わりに物理テーブルに置き換えることができます。

EDIT フィードバックとして:外側のクエリで必要だったので、クエリに苦労したと思います:
1.フィルタリング後にすべてのレコードで集計関数を実行します。
2. フィルターで集計関数を使用します。
group by ステートメントが存在する場合は最初のことを実行できませんが、group by ステートメントが存在しない場合は 2 番目を実行できません。

したがって、最終結果では、追加のサブクエリで2番目を実行しながら、最初のクエリを外側のクエリに保持しました。

于 2013-08-22T12:56:03.803 に答える
1

これはかなり大変でした。SAS を 12 年間使用した後、GROUP BY なしで HAVING を使用した/見たことを思い出せません。予期しない結果が生じると思います。

したがって、単一のクエリの場合、グループ化が 2 回行われるため、私のソリューションはあまり良くありません。

単一のクエリ バージョン:

proc sql;
select avg(betprice) 
    from ( select
                  betprice
                , count(*) as count_betprice
                from work.have
                group by betprice) /* first summary */
    where count_betprice
                = select max(count_betprice)
        from
          (select
                  betprice
                , count(*) as count_betprice
                from work.have
                group by betprice) /* same summary here */;
quit;

同じサブクエリの代わりに中間テーブル (または必要に応じてビュー) を使用して、少し単純化します。

proc sql;
create table work.freq_sum
        as select
                betprice
                , count(*) as count_betprice
                from work.have
                group by betprice
;
select avg(betprice) 
    from work.freq_sum
    where count_betprice
                = select max(count_betprice) from work.freq_sum;
quit;

Pls、PROC MEANS によって MODE や MEDIAN などの統計を計算できることに注意してください。

proc means data=have n mean mode median;
var betprice;
run;
于 2013-08-22T12:57:56.613 に答える