我使用以下代码在一个库中自动拆分数据集。
以下是我的代码。
%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(变量名称),因此无法手动拆分数据集。在这种情况下,我如何改进我的代码来改进这段代码?
答案 0 :(得分:1)
这是一个磁盘空间问题。 " I / O"数据集错误往往不是因为内存问题而是因为磁盘空间而发生。您的数据集有很多重复值,这在压缩方面对您有好处。你想做的三件事:
<强> 1。将列长度设置为仅需要
可以使用attrib
或length
语句对每个变量执行此操作。我发现有用的方法是在初始数据集上使用%squeeze()
macro,将这些属性保存到单独的空数据集,然后使用create table like
保留这些属性,而不必运行{{1}再次。例如:
%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
语句中的第一个表。
<强> 2。使用set
数据集选项
压缩数据集可以节省大量空间。 SAS使用两种算法:一种适用于字符变量,一种适用于数字。在你的情况下,尝试两者,看看哪个给出了最好的结果。
compress
第3。检查正在使用的内存量
打开系统选项%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;
以获取每个步骤使用的内存量的详细视图。如果使用的内存太多,则需要采用不同的方法来减少总内存。
例如,您在单个数据步骤中输出所有内容。您可以将其转换为多个单独的数据步骤,而不是一个大的步骤。
答案 1 :(得分:0)
SAS日志照片中的关键字是:
NOTE: Table WORK.TMP4 created, with 17329 rows and 2 columns.
您无法在一个数据步骤中创建17,000个数据集。 你为什么要这么做?您需要在多个数据步骤中执行此操作,或者更好地找到原始问题的不同解决方案。