2013-08-22 3 views
1

특정 변수 목록의 모드를 얻으려고합니다. 모드가 고유하지 않은 경우 모드의 평균을 반환하여 (더 큰 쿼리에서) 모드를 가져 오는 하위 쿼리가 두 값을 반환하지 않도록하고 싶습니다. 그러나 모드가 고유 한 경우 평균 쿼리는 어떤 이유로 든 누락 된 값을 반환합니다.SAS : 단일 관측치의 AVG()

나는 다음과 같은 샘플 데이터가 :

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; 

이 쿼리를 변경하여 모드 나 가장 자주 사용되는 값의 평균을 반환 할 수 있습니다.

감사합니다.

+1

왜 모드 평균을 원하십니까? 통계적 관점에서 볼 때 흥미로운 용어는 아닙니다. MODE가 정말 유용한 유일한 이유는 배포판을 보는 것입니다. 평균을 취하는 경우 MODE = 4로 설정하면 단일 모드 4의 이항 분포이거나 3과 4 및 5가 모두 같은 고원 또는 1과 7이있는 매우 비뚤어진 평평한 고원입니다. – Joe

+0

나는 그것이 재미 있다고 생각한다! 나는 처음 10 배나 20 배에 해당하는 betprice의 선택에 따라 선수들을 분류하고 싶다. Betprice는 연속 변수가 아니며 4 개의 이산 값, 즉 6, 2, 1.83 및 1.05 만 있습니다. 처음 10 베팅에 따라 플레이어를 어떻게 순위 매 깁니까? 평균을 취하면 값 6이 값 1.05에서 너무 멀기 때문에 좋지 않습니다. 플레이어가 1.05에서 7 개의 베팅을하고 6에서 3 개의 베팅을한다면 그는 1.05 명의 플레이어로 평가되어야한다고 말하고 싶습니다. 평균을 취하면 거의 3입니다. 2의 가격으로 10 베팅을하는 사람보다 평균이 더 높습니다. – user2146441

+1

모드 자체의 평균은 재미 있다고 생각하지 않습니다. 그것이 넥타이라면, 당신이하는 일은 당신의 분석에 달려 있지만, 그 의미가 얼마나 유용한 지 이해할 수 없습니까? 4 개의 이산 값이 있기 때문에 "모드 평균"은 특정 쌍의 평균/모드이지만, 3.55를 자주 베팅 한 사람과 비슷하게 1.05와 6을 베팅하는 사람입니다 (가능 했습니까?). 나 한테는 그렇게 보이지 않아. – Joe

답변

1

12 년 동안 SAS에서 작업 한 후에도 GROUP BY없이 HAVING을 사용했음을 기억하지 못합니다. 예기치 않은 결과가 나오는 것 같습니다.

단일 쿼리의 경우 내 솔루션은 그룹화를 두 번 수행하므로별로 좋지 않습니다.

단일 쿼리 버전 :

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에 의한 MODE와 MEDIAN과 같은 의미 :

proc means data=have n mean mode median; 
var betprice; 
run; 
+0

전체 'have'테이블의 각 행에는 타임 스탬프, 사용자 이름, betprice 및 다른 컬럼이 있습니다. 각 사용자 이름에 대해 여러 항목이 있습니다. 더 큰 쿼리는 다른 사용자 명단과 함께 1 ~ 20 번째 베팅에서 각 사용자 이름과 플레이어 평균 베팅을 추출합니다. 당신이 제안하는 첫 번째 쿼리 버전은 이것에 대해 잘 작동합니다! – user2146441

+1

PROC UNIVARIATE는 여러 모드를 반환하기 때문에 모드에 더 적합합니다. 나 또한 단일 쿼리 버전을 사용하지 않는 것이 좋습니다 (vasja가 잘 보이는 것처럼). 잘못된 것이 아니기 때문에가 아니라 두 번째를 읽고 유지하는 것이 더 쉽습니다 (특히 첫 번째 부분을 보는 경우). 복잡한 복잡한 쿼리를 작성하는 것은 '직업 안정'을 시도하지 않는 한 좋은 코딩 방법의 징후가 아닙니다. – Joe

+0

나는 플레이어 이름, 베팅 금액, 각 금액에 베팅 금액 등으로 베팅 테이블에서 작업하고 각 플레이어에 대해 고유 한 행이있는 집계 테이블을 만드는 중이므로이 값을 즉시 분할하지 않습니다. 일련의 뷰, 중간 데이터 스토어 및 임시 테이블로 구성됩니다. 'subselects'를 사용하여 각 플레이어 행의 열 데이터를 채우는 것이 더 간 단한 것 같습니다. 어쩌면 나는이 잘못된 길을 가고있다. . – user2146441

2

먼저, having 절을 사용하는 동안 외부 쿼리에 그룹 by 문이 없음을 유의하십시오. 어느 것이 좋습니다.

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. 필터에서 집계 함수를 사용하십시오.
그룹 별 성명서를 사용하지 않고 두 번째 성취를 할 수없는 동안 성명 별 그룹 성명서를 사용하여 첫 번째 성전을 수행 할 수 없습니다.

그래서 결국 하위 쿼리를 추가로 수행하면서 외부 쿼리에서 첫 번째 쿼리를 유지했습니다.

3

당신은 SAS에 있습니다. 그게 좋은 일 이니까 통계를 먹었어.

ods output modes=want; 
proc univariate data=have modes; 
var betprice; 
run; 
ods output close; 

proc means data=want; 
var mode; 
output out=final(keep=betprice) mean=betprice; 
run; 

이 작업은 그리 오래 걸리지 않을 것이며, 다른 프로그래머가하는 일이 훨씬 명확하고 코드 작성이 매우 쉽습니다. 모드의 평균을 취하지 않았다면 한 단계로 수행 할 수 있습니다.

+0

좋아, UNIVARIATE가 하나 이상의 MODE를 생성 할 수 있다는 것을 알지 못했습니다. 더 작은 것을 선택하는 평균과 비교하십시오! – vasja

+1

단일 변이 및 의미는 기본적으로 둘 중 가장 작은 것을 선택하십시오. Univariate는 (PROC UNIVARIATE 문에서 modes 옵션을 사용하여) 요청하면이 방법을 여러 번 생성 할 수 있지만 출력 문이 아닌 ODS OUTPUT을 사용하여 출력해야합니다. – Joe