2013-08-22 187 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不是一個連續變量,只有四個離散值:6,2,1.83和1.05。我如何根據他們的前10次投注對玩家進行排名?如果我取平均值,它不是很好,因爲值6距離值1.05太遠了。如果一名球員在1.05時有7次投注,在6次時有三次投注,我認爲他應該被評爲1.05。如果我拿平均水平,差不多是3:平均水平高於以2的價格進行10次投注的人。 – user2146441

+1

雖然我不認爲模式本身的意思很有趣。如果它是一個平行線,那麼你對它的處理取決於你的分析,但我不明白這個平均值是如何有用的?既然你有四個離散值,我想很明顯他們的「模式均值」是一對特定對的平均值/模式,但是有人投注1.05和6的頻率類似於頻繁投注3.55的人(這是可能的)嗎?看起來不像我。 – Joe

回答

1

這非常困難,在與SAS合作12年之後,我記不清使用HAVING而沒有使用GROUP BY,我猜測它會產生意想不到的結果。

因此,對於單個查詢,我的解決方案不是很好,因爲它進行了兩次分組。

一個查詢版本:

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; 

請注意,你可以計算統計像MODE和MEDIAN通過PROC MEANS:

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

完整「有」表中的每一行都有一個時間戳,一個用戶名,一個betprice和一些其他列。每個用戶名有多個條目。較大的查詢將提取每個用戶名和玩家在1日至20日的平均betprice以及其他一些統計數據。您建議的第一個單一查詢版本適用於此! – user2146441

+1

PROC UNIVARIATE更適合模式,因爲它會返回多種模式。我也建議不要使用單個查詢版本(因爲vasja似乎也是這樣),並不是因爲它有什麼問題,而是更容易閱讀和維護第二個版本(尤其是如果您將第一部分視爲一個視圖)。寫大複雜的查詢並不代表良好的編程習慣,除非您正在嘗試'工作安全性'。 – Joe

+0

因爲我正在從一個賭桌上玩家名字,賭價,賭注金額等每一行,然後創建一個聚合表與每個球員獨特的行,我不會立即看到分裂這個值進入一系列視圖,中間數據包和臨時表。使用'subselects'填充每個玩家行的列數據似乎更加簡單。也許我在這方面走錯了路。 。 – user2146441

2

首先,請注意,當您使用having子句時,外部查詢中沒有group 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操作,您可能希望用物理表替換它。

編輯 反饋:我相信你,因爲你想要的外部查詢與查詢掙扎:
1.過濾後在所有記錄執行聚合功能。
2.在過濾器中使用聚合函數。
如果沒有按語句提供語句,則無法在第二個語句中執行第一個語句,而您無法執行第二個語句。

因此最終的結果是,我在外部查詢中保留了第一個,而在另一個子查詢中執行了第二個查詢。

3

你在SAS,爲什麼不讓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。比較選擇較小的MEANS?? – vasja

+1

單變量和均值默認情況下選擇最小的一個。如果您要求它(PROC UNIVARIATE語句中的模式選項),那麼單變量也可以產生多種方式,但它必須與ODS OUTPUT一起輸出,而不是輸出語句。 – Joe