簡體   English   中英

SAS代碼改進,可使用宏拆分多個數據集

[英]SAS- Code improvement for spliting multiple dataset with macro

我使用以下代碼在一個庫中自動拆分數據集。

  1. 首先,我使用proc sql將所有數據集放入表中並編號。
  2. 其次,我還使用proc sql讀取每個數據集中的內容,以便設置拆分規則。 更具體地說,拆分過程基於兩個變量:date_1和_ric。 顯然,date_l_是日期變量。 _ric是用於標識股票名稱的變量。 該步驟的結果如下所示:

在此處輸入圖片說明

  1. 最后,我將%do j = 1%用於&obs。 分割數據集。

以下是我的代碼。

%macro split(sourcelib=,source=,result=);
proc sql noprint;  /*read datasets in a library*/
create table mytables as
select *
from dictionary.tables
where libname = &sourcelib 
order by memname ;

select count(memname) 
into:numb 
from mytables;

%let numb=&numb.;  /*give a number to datasets in the library*/

select memname
into :memname1-:memname&numb.
from mytables;
quit;

%do i=1 %to &numb.;
proc sql noprint;
create table tmp&i as
select distinct date_l_, _ric
from &source.&&memname&i;

select count(*)
into :obs
from work.tmp&i.;

%let obs=&obs.; /*read the variable 'date_l_' and '_ric' in each dataset*/

select date_l_, _ric, catx("_", "&result.", substr(_ric, 1, 13), date_l_)
into :date_l_1-:date_l_&obs., :ric1-:ric&obs., :setname1-:setname&obs.
from work.tmp&i;
quit;
%end;

data 
%do j = 1 %to &obs.;   /*set rules for separated dataset*/
&&setname&j
%end;
;
set
%do i=1 %to &numb.;
&source.&&memname&i
%end;
; 
select;
%do j = 1 %to &obs.;
when(_ric = "&&ric&i" and date_l_ = &&date_l_&i) output &&setname&j;
%end;
end;
%mend;

%split(sourcelib='DATA',source=DATA.,result=AXP.);

但是,我遇到了如下所示的錯誤: 在此處輸入圖片說明 根據問題注釋:如果SAS必須獲取內存才能處理直接訪問綁定庫,並且內存已經用完,則SASLOG中可能會出現錯誤消息。

由於我有大約100個數據集,並且禁忌使用各種數據和RIC(變量名),因此無法手動拆分數據集。 在這種情況下,如何改進我的代碼以改進此代碼?

這是磁盤空間問題。 “ I / O”數據集錯誤往往不是由於內存問題而是由於磁盤空間而發生。 您的數據集有很多重復的值,這對壓縮來說很有利。 您想做的三件事:

1.將列長度設置為僅所需的長度

可以使用attriblength語句為每個變量完成此操作。 我發現有用的一種方法是在初始數據集中使用%squeeze() ,將這些屬性保存到單獨的空數據集中,然后使用create table like保留這些屬性,而不必再次運行%squeeze() 例如:

/* Shrink the dataset */
%squeeze(everything, everything_squeezed);

/* Save a copy of all these attributes in an empty dataset */
proc sql noprint;
    create table everything_attribs like everything_squeezed;
quit;

如果完整的數據集定期更新或覆蓋而丟失了屬性,這將很有用。 everything_attribs用作set語句中的第一個表。

2.使用compress數據集選項

壓縮數據集可以節省大量空間。 SAS使用兩種算法:一種適用於字符變量,一種適用於數字。 在您的情況下,請同時嘗試兩者,看看哪種方法效果最好。

%do i=1 %to &numb.;
proc sql noprint;
create table tmp&i(compress=yes) as
select distinct date_l_, _ric
from &source.&&memname&i;

select count(*)
into :obs
from work.tmp&i.;

%let obs=&obs.; /*read the variable 'date_l_' and '_ric' in each dataset*/

select date_l_, _ric, catx("_", "&result.", substr(_ric, 1, 13), date_l_)
into :date_l_1-:date_l_&obs., :ric1-:ric&obs., :setname1-:setname&obs.
from work.tmp&i;
quit;
%end;

data 
%do j = 1 %to &obs.;   /*set rules for separated dataset*/
&&setname&j(compress=yes)
%end;
;
set
%do i=1 %to &numb.;
&source.&&memname&i
%end;
; 
select;
%do j = 1 %to &obs.;
when(_ric = "&&ric&i" and date_l_ = &&date_l_&i) output &&setname&j;
%end;
end;
%mend;

3.檢查正在使用多少內存

打開系統選項fullstimer以獲得每個步驟使用的內存量的詳細視圖。 如果使用了過多的內存,則需要采取其他方法使用更少的總內存。

例如,您要在單個數據步驟中輸出所有內容。 您可以將其轉換為多個單獨的數據步驟,而不是一個大步驟。

您的SAS日志照片中的關鍵行是這樣寫的:

NOTE: Table WORK.TMP4 created, with 17329 rows and 2 columns.

您不能在一個數據步驟中創建一萬七千個數據集。 你為什么還要這么做? 您將需要在多個數據步驟中執行此操作,或者更好地還是找到針對原始問題的其他解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM