[英]SAS- Code improvement for spliting multiple dataset with macro
我使用以下代碼在一個庫中自動拆分數據集。
以下是我的代碼。
%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.將列長度設置為僅所需的長度
可以使用attrib
或length
語句為每個變量完成此操作。 我發現有用的一種方法是在初始數據集中使用%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.