我正在运行一个巨大的dset,填充一个独特值的哈希值。在巨大的datastep结束时,我将哈希内容吐出到第二个数据集。
巨大的数据集足以导致内存不足错误 - 具体来说:
> ERROR: Hash object added nnnnnn items when memory failure occurred.
> FATAL: Insufficient memory to execute DATA step program. Aborted
> during the EXECUTION phase.
所以我想定期将哈希内容写入dset&然后刷新哈希&继续。为了做到这一点,我需要为哈希输出数据集提供唯一的名称。这是我的代码的一个小版本,用于说明问题:
data huge ;
do i = 1 to 50 ;
recnum = ceil(i / 15) ;
output ;
end ;
run ;
* Write the hash out every 20 records. ;
%let chunk_size = 20 ;
data huge ;
set huge end = alldone ;
if _n_ = 1 then do ;
declare hash myhash() ;
myhash.definekey('i') ;
myhash.definedata('i', 'y') ;
myhash.definedone() ;
call missing (y) ;
end ;
y = i * 3 ;
myhash.ref() ;
if mod(_n_, &chunk_size) = 0 then do ;
call symput("chunk_num", put(_n_/&chunk_size, z2.0)) ;
myhash.output("dataset: part&chunk_num") ;
end ;
if alldone then do ;
myhash.output("dataset: part_final") ;
end ;
run ;
呼叫symput()正在运行& var得到了创建(我可以symget()将它放入dset变量,frx。)但我似乎无法在该哈希输出语句中使用它。我得到的错误是:
WARNING: Apparent symbolic reference CHUNK_NUM not resolved.
如何使用my& chunk_num宏var命名我的临时哈希输出数据集?
答案 0 :(得分:1)
答案是 - 为此使用宏是错误的。我可以使用普通的数据集变量,如下所示:
%let chunk_size = 20 ;
data huge ;
set huge end = alldone ;
if _n_ = 1 then do ;
declare hash myhash() ;
myhash.definekey('i') ;
myhash.definedata('i', 'y') ;
myhash.definedone() ;
call missing (y) ;
end ;
y = i * 3 ;
myhash.ref() ;
if mod(_n_, &chunk_size) = 0 then do ;
hash_dset_name = cats("chunk_num", put(_n_/&chunk_size, z2.0)) ;
myhash.output(dataset: hash_dset_name) ;
myhash.clear() ;
end ;
if alldone then do ;
myhash.output(dataset: "part_final") ;
end ;
drop hash_dset_name ;
run ;
答案 1 :(得分:1)
您无需在OUTPUT方法调用中对数据集名称进行硬编码。您可以使用变量甚至表达式。
if mod(_n_, &chunk_size) = 0 then do ;
myhash.output(dataset: cats('part',put(_n_/&chunk_size,z2.))) ;
end ;