4

3400 を超える CSV ファイルがあり、サイズは 10kb から 3mb までさまざまです。各 CSV ファイルstockticker-Ret.csvにはstockticker、次のような一般的なファイル名があります。私の SAS コードは、まずstockticker-Ret.csv、SAS データセット内のファイルからすべての株式ティッカー名をロードすることから始めます。各ティッカーをループして.csv、 という SAS データセットに適切なファイルをロードし、wantいくつかのデータステップを適用して、各ティッカーwantの最終的なデータセットを という SAS データセットに保存します。ご想像のとおり、このプロセスには長い時間がかかります。このプロセスを高速化するために、以下のコード を改善する方法はありますか?wantglobalDO LOOP

/*Record in a sas dataset all the csv file name to extract the stock ticker*/
    data yfiles;
    keep filename;
    length fref $8 filename $80; 
    rc = filename(fref, 'F:\data\'); 
    if rc = 0 then do; did = dopen(fref); 
    rc = filename(fref); end; else do; length msg $200.; msg = sysmsg(); put msg=; did = .; end;
    if did <= 0 then putlog 'ERR' 'OR: Unable to open directory.';
    dnum = dnum(did);
    do i = 1 to dnum; filename = dread(did, i); /* If this entry is a file, then output. */ fid = mopen(did, filename); if fid > 0 then output; end;
    rc = dclose(did);
    run;

/*store in yfiles all the stock tickers*/
    data yfiles(drop=filename1 rename=(filename1=stock));
    set yfiles;
    filename1=tranwrd(filename,'-Ret.csv','');
    run;

    proc sql noprint;
    select stock into :name separated by '*' from work.yfiles;
    %let count2 = &sqlobs;
    quit;


    *Create the template of the desired GLOBAL SAS dataset;
    proc sql;
    create table global
    (stock char(8), time_gap num(5), avg_ret num(5));
    quit;

    proc sql;
    insert into global
    (stock, time_gap,avg_ret)
    values('',0,0);
    quit;

    %macro y1;
    %do i = 1 %to &count2;
    %let j = %scan(&name,&i,*);
    proc import out = want datafile="F:\data\&j-Ret.csv"
    dbms=csv replace;
    getnames = yes;
    run;


    data want;
    set want; ....

    ....[Here I do 5 Datasteps on the WANT sasfile] 


/*Store the want file in a global SAS dataset that will contain all the stock tickers from the want file*/

    data global;
    set global want; run;

    %end;
    %mend y1;
    %y1()

ご覧のとおり、グローバル SAS データセットは、want保存するすべてのデータセットに対して展開されglobalます。

4

1 に答える 1

4

PROC IMPORTファイルに共通のレイアウトがあると仮定すると、ループを使用してインポートしたり実行したりしないでください。1 つのデータステップでそれらをすべて読み取る必要があります。いいえ:

data want;
length the_file $500;
infile "f:\data\*.csv" dlm=',' lrecl=32767 dsd truncover firstobs=2 filename=the_file;
input
myvar1 myvar2 myvar3 myvar4;
stock_ticker=scan(the_file,'\',-1); *or whatever gets you the ticker name;
run;

同一のレイアウトがない場合、または読み込みが複雑な場合は、それよりも複雑な入力ステートメントが必要になる場合がありますが、ほとんどの場合、この方法で実現できます。多くの PROC IMPORT を伴う do ループは、IMPORT のオーバーヘッドのために常に非効率的です。

フォルダー内のすべての .csv ファイルが必要ない場合 (および必要なマスクを書き込めない場合)、またはレイアウトのサブセットがある場合は、FILEVAR オプションを使用してファイルを共通のデータセット。その後、必要に応じて、さまざまな入力ステートメントに分岐できます。

data want;
set yfiles;
infile a filevar=filename;
if filevar [some rule] then do;
input ... ;
end
;else if ... then do;
input ... ;
end;
run;
于 2014-01-22T19:04:37.040 に答える