2016-10-27 17 views
0

私は約30の変数(列)を持つ約5,000万レコードのデータセットを持っています。 各変数のデータセットをランク付けする必要があります。大きなデータセットで複数の変数をランク付けする方法は?

この大きなデータセットには大量のメモリが必要なため、Procランクは機能しません。

ランクを手動で与えるには、それぞれの変数列でデータセットをソートし、数式を使用してランク付けする必要があります。しかし問題は、非常に長い時間がかかり、実現不可能な30の変数でデータセットを30回ソートしなければならないことです。

この場合、どのような代替手段を使用できますか?

答えて

0

あなたは多くのオプションなしで厳しい状況にあります。毎回30の変数をソートして保持すると、処理時間が大幅に増加します。私があなただったら、ランク付けしたい変数とシーケンス番号を数式を適用したままにしておき、最後にまとめてマージします。これを行うには、データセット内の各変数をループして、すべての変数をまとめてマージする必要があります。それはあなたの処理時間を減少させる助けになる下回ると場合の例を参照してください。

** PUT ALL VARIABLES INTO LIST **; 
PROC SQL NOPRINT; 
    SELECT DISTINCT(NAME) 
    INTO :VARS SEPARATED BY " " 
    FROM DICTIONARY.COLUMNS 
    WHERE LIBNAME = 'SASHELP' AND MEMNAME = 'FISH'; 
QUIT; 

%PUT &VARS.; 

** CREATE SEQUENCE NUMBER IN FULL DATA **; 
DATA FISH; SET SASHELP.FISH; 
    SEQ=_N_; 
RUN; 

** LOOP OVER EACH VARIABLE TO ONLY PROCESS THAT VARIABLE AND SEQUENCE -- REDUCES PROCESSING TIME **; 
%MACRO LOOP_OVER(VARS); 
    %DO I=1 %TO %SYSFUNC(COUNTW(&VARS.)); 
     %LET VAR = %SCAN(&VARS,&I.); 
     DATA FISH_&I.; SET FISH (KEEP=SEQ &VAR.); 
     RUN; 

     /* INSERT YOUR FORMULA CODE HERE ON FISH_&I. DATA (MINE IS AN EXAMPLE) */ 
     PROC SORT DATA = FISH_&I.; 
      BY &VAR.; 
     RUN; 

     DATA FISH1_&I.; SET FISH_&I.; 
      BY &VAR.; 
      RANK_&VAR = _N_; 
     RUN; 

     /* RESORT FINAL DATA BY SEQUENCE NUMBER VARIABLE */ 
     PROC SORT DATA = FISH1_&I.; 
      BY SEQ; 
     RUN; 
    %END; 
%MEND; 

%LOOP_OVER(&VARS.); 

** MERGE ALL SUBSETS BACK TOGETHER BY THE ORIGINAL SEQUENCE NUMBER **; 
DATA FINAL; 
    MERGE FISH1_:; 
    BY SEQ; 
    DROP SEQ; 
RUN; 
+0

あなたは%DO Iの最初の2つのステップを1つにまとめることでパフォーマンスをさらに向上させることができます。 PROC SORT data = fish(keep = seq&var)out = fish_&i; また、データステップのVIEWを使用してランクを計算し、それを最後のPROC SORTへの入力として使用します。 –

0

あなただけの十分位数/パーセンタイルなどにランク付けするのではなく、すべて50メートルの行全体で50メートルまで1から完全にランクする必要がある場合は、次のことができるようにすべきですproc summaryを使用し、qmethod=P2を使用し、適切なqmarkers設定を使用して、はるかに少ない量のメモリを使用して正解を近似してください。それは良い考えであるかどうか、 http://www.cs.wustl.edu/~jain/papers/ftp/psqr.pdf

0

私はわからない:

このアプローチでは、P-二乗アルゴリズムを使用しています。しかし、あなたは、ハッシュオブジェクトを使用することをお勧めします。オブジェクトがRAMにロードされます。 30 Mioの数値観測があると仮定すると、間違っていなければ、約(2 * 8bytes)* 50 mio = 800MBのRAMが必要になります。

コードは(、変数をループにFoxersマクロを使用してデータセットと二つの変数を持つ小さなテストデータセットから変数のリストを取得するには少しヘルパーマクロ)を次のようになります。

%Macro GetVars(Dset) ; 
%Local VarList ; 
/* open dataset */ 
%Let FID = %SysFunc(Open(&Dset)) ; 
/* If accessable, process contents of dataset */ 
%If &FID %Then %Do ; 
    %Do I=1 %To %SysFunc(ATTRN(&FID,NVARS)) ; 
    %Let VarList= &VarList %SysFunc(VarName(&FID,&I)); 
%End ; 
/* close dataset when complete */ 
%Let FID = %SysFunc(Close(&FID)) ; 
%End ; 
&VarList 
%Mend ; 

data dsn; 
input var1 var2; 
datalines; 
1 48 
1 8 
2 5 
2 965 
3 105 
4 105 
3 85 
; 
run; 


%MACRO LOOP_OVER(VARS); 
%DO I=1 %TO %SYSFUNC(COUNTW(&VARS.)); 
    %LET var = %SCAN(&VARS,&I.); 
    data out&i.(keep=rank&i.); 
     if 0 then set dsn; 
     if _N_ =1 then 
     do; 
      dcl hash hh(ordered:'A'); 
      dcl hiter hi('hh'); 
      hh.definekey("&var."); 
      hh.definedata("&var.","rank&i."); 
      hh.definedone(); 
     end; 

     /*Get unique combination variable and point in dataset*/ 
     do while(not last); 
      set dsn end=last; 
      hh.ref(); 
     end; 

     /*Assign ranks within hash object*/ 
     rc=hi.first(); 
     k = 1; 
     do while(rc=0); 
      rank&i.=k; 
      hh.replace(); 
      k+1; 
      rc=hi.next(); 
     end; 

     /*Output rank to new dataset in original order of observations*/ 
     do while(not theend); 
      set dsn end=theend; 
      hh.find(); 
      output; 
     end; 
     /*If data can be sorted according to the rank (with no duplicates) use: 
     hh.output("out&i."); 

     &outi. will then have variables &var. and rank&i. 
     However, the merging below may not be sensible anymore 
     as correspondence between variables is not preserved. 
     There will also be no duplicates in the dataset. 
     */ 

    run; 
%END; 

%MEND LOOP_OVER; 

%LOOP_OVER(%GetVars(dsn)); 


/*Merge all rank datasets to one large*/ 
data all; 
merge out:; 
run; 
関連する問題