0

~5M obs の入力でプログラムを実行すると、メモリ不足エラーが発生します。および 153 個の変数。

~40,000 obs で同じプログラムを実行する場合。- プログラムが実行され、完了します。入力obsの数を増やしようとすると。100K を超える - エラーが表示されます: メモリが不足しています。

以下のヒントに従って、いくつかのボックスのチェックを外してみました。

1.Tools ► Options ► Results General ► deselect all Result Formats.
2.Tools ► Options ► Results General ► deselect Open generated data/results automatically.
3.Tools ► Options ► Results General ► deselect Link handcoded ODS results.
4.Tools ► Options ► SAS Programs ► deselect Automatically direct results back to SAS Enterprise Guide.

まだ動作していません。

私は Enterprise Guide 5.1 を使用していますが、最終的には Data Integration Studio 4.6 の User Written Code トランスフォーメーションに作業コードを挿入します。

このプログラムを機能させる方法を知っている人はいますか?

編集済み

これは、エラー メッセージの原因となるコードの一部です。

 data _null_;
        set all_include_Stornos ;
        IF TREATMENT_IND = 1 AND DDS_ROW_IND NE 1 THEN DO;
        CALL EXECUTE ('%STORNO_TKUFA ('||POLICY_RK||');');
        CALL EXECUTE ('%UPDATE (STORNO_TKUFA_CUMULATE);');
        END;
        IF TREATMENT_IND in (4) AND DDS_ROW_IND NE 1  THEN DO;

            CALL EXECUTE ('%HAKPAA ('||POLICY_RK||','||POLICY_VERSION||');');
            call execute ('%UPDATE(HAKPAA_CUMULATE);');


        END;

        IF TREATMENT_IND  = 5  AND DDS_ROW_IND NE 1  and count_bitul_no <2  or (count_bitul_no >1 and max_bitul_ver = policy_verSion ) THEN DO;
            CALL EXECUTE ('%BITUL ('||POLICY_RK||','||POLICY_VERSION||');');
            CALL EXECUTE ('%UPDATE(BITUL_CUMULATE);');

        END;

        IF TREATMENT_IND = 6 AND DDS_ROW_IND NE 1  THEN DO;
        CALL EXECUTE ('%LAST_STATE ('||POLICY_RK||','||POLICY_VERSION||');'); 
        CALL EXECUTE ('%UPDATE (LAST_STATE_calc);');
        END;

        IF DDS_ROW_IND NE 1 and ((PREV_TREATMENT_IND = 4 AND TREATMENT_IND NOT IN (1,2,5)) or treatment_ind = 3) THEN DO;
            CALL EXECUTE ('%HAFSHARA ('||POLICY_RK||','||POLICY_VERSION||');');
            CALL EXECUTE ('%UPDATE (HAFSHARA_CUMULATE);');
        END;

            IF TREATMENT_IND = 2 AND POLICY_VERSION - 1 = max_bitul_ver AND DDS_ROW_IND NE 1  THEN DO;
        CALL EXECUTE ('%STORNO_BITUL ('||POLICY_RK||','||POLICY_VERSION||');');
        CALL EXECUTE ('%UPDATE (STORNO_BITUL_CUMULATE);');
        END;
RUN; 

これらは、treat_ind = 5 のときに実行される 2 つのマクロ (短縮) です。

%macro BITUL (pol_rk , pol_ver );


    proc sql;
    create table macro_BITUL
    as select * from all_include_Stornos
    where policy_rk = &pol_rk
    and treatment_ind_5 = &pol_ver 
    order by policy_rk, policy_version;
    quit;



    data BITUL_calc;
    set macro_BITUL;
    BY POLICY_RK;

    IF LAST.policy_rk THEN ACT_DAILY_AMT_END_DT = POLICY_VERSION_END_DT;
            ELSE ACT_DAILY_AMT_END_DT = NEXT_POLICY_VERSION_START_DT; 

    VERSION_EXPOSURE_DAYS_NO = ACT_DAILY_AMT_END_DT - ACT_DAILY_AMT_START_DT + 1;

    BITUL_DURATION =  (POLICY_EXPIRATION_DT_5 - POLICY_VERSION_START_DT + 1) / (POLICY_VERSION_END_DT_5 - POLICY_VERSION_START_DT + 1);

    GAINED_NET_PREMIUM_V_AMT  = NET_PREMIUM_V_AMT *BITUL_DURATION;
    .
    .
    .
    GAINED_NET_COMMISION_B_IB_V_AMT = PRODUCR_B_NET_COMM_IB_V_AMT * BITUL_DURATION; 
    run;

    /**/


    PROC SQL;
    CREATE TABLE TOTAL_GAINED AS 
    SELECT POLICY_RK,
    SUM(GAINED_NET_PREMIUM_V_AMT) AS TOT_GAINED_NET_PREMIUM_V_AMT,
    SUM(GAINED_NET_FEES_V_AMT) AS TOT_GAINED_NET_FEES_V_AMT,
    .
    .
    .
    SUM(GAINED_NET_COMMISION_B_IB_V_AMT) AS TOT_GAINED_NET_COMMN_B_IB_V_AMT 

    FROM BITUL_calc
    GROUP BY POLICY_RK;
    QUIT;

    PROC SQL;
    CREATE TABLE BITUL_calc_AND_TOTALS AS
    SELECT A.* , 
    TOT_GAINED_NET_PREMIUM_V_AMT,
    .
    .
    JOIN TOTAL_GAINED AS B
    ON
    (A.POLICY_rK = B.POLICY_RK
    )order  by policy_rk, policy_version;
    QUIT;




    DATA bitul_CALCULATED;
    SET BITUL_calc_AND_TOTALS;
    IF TOT_GAINED_NET_PREMIUM_V_AMT = 0 THEN CALCULATED_NET_PREMIUM_V_AMT = 0; 
        ELSE CALCULATED_NET_PREMIUM_V_AMT = NET_PREMIUM_AMT_5 * GAINED_NET_PREMIUM_V_AMT / TOT_GAINED_NET_PREMIUM_V_AMT;
    .
    .
        ELSE CALC_NET_COMMISION_B_IB_V_AMT = PRODUCR_B_NET_COMM_IB_AMT_5 * GAINED_NET_COMMISION_B_IB_V_AMT / TOT_GAINED_NET_COMMN_B_IB_V_AMT;


    .
    .
    .
    .
    .


    run;

    DATA BITUL_CUMULATE;
    SET bitul_CALCULATED;
.
.
.
.
.
.
run;    

%mend ;




%MACRO UPDATE (TABLE_NAME);
        PROC SQL;
            DELETE FROM all_include_Stornos
            WHERE CATS(POLICY_RK,POLICY_VERSION) IN ( SELECT CATS(POLICY_RK,POLICY_VERSION) FROM     &TABLE_NAME);
            INSERT INTO all_include_Stornos
select *    FROM &TABLE_NAME
            ;QUIT;

/*          PROC SORT DATA=all_include_Stornos OUT=all_include_Stornos; BY POLICY_RK     POLICY_VERSION;RUN;*/

%MEND;
4

4 に答える 4

1

これに基づいて、「どのデータステップで私を追い出すかを知っています。つまり、ifステートメントに従って異なるマクロを呼び出すデータnullです。」

仕組みを見てみましょうCall Execute。( http://www2.sas.com/proceedings/sugi22/CODERS/PAPER70.PDFが参考になります)

基本的にCall Execute、マクロ コードはすぐに解析されますが、現在のデータ ステップが終了するまで、結果の SAS ステップがキューに入れられます。data _null_;つまり、SAS がそのステップの終了時に実行されるように格納している数百万行の SAS コードをメモリ内に構築している可能性があります。最終的に、これは非常に大きくなり、SAS が失敗します。

これに対処する方法は?data _null_;ステップをチャンクに分割するマクロを作成するだけです。マクロ変数へproc sqlのレコード数を選択するために使用できます。all_include_Stornos次に、マクロ ループを使用してデータ ステップを複数回実行し、 と を使用firstobsobsて毎回データの一部のみをヒットします。そうすれば、構築されたバッファーをcall execute適切なサイズに抑えることができます。これにより、メモリ不足を防ぐことができます。

于 2014-01-07T13:01:08.703 に答える