当我使用PROC EXPORT时,如何阻止SAS为每个字符串变量添加额外的空字节?

时间:2015-06-10 20:48:29

标签: sas stata

当我使用PROC EXPORT将数据集导出为Stata格式时,SAS 9.4会自动扩展为每个字符串变量的每次观察添加一个额外的(空)字节。例如,在此数据集中:

data test1;
    input cust_id   $ 1
          month       3-8
          category  $ 10-12 
          status    $ 14-14
;
datalines;
A 200003 ABC C
A 200004 DEF C
A 200006 XYZ 3
B 199910 ASD X
B 199912 ASD C
;
quit;

proc export data = test1
    file = "test1.dta"
    dbms = stata replace;
quit;

最终Stata文件中的变量cust_idcategorystatus应为str1str3str1,以及因此,每次观察分别占用1个字节,3个字节和1个字节。但是,SAS会自动为每个观察添加一个额外的空字节,从而将其数据类型扩展为输出的Stata文件中的str2str4str2数据类型。

这是非常有问题的,因为每个观察每个字符串变量的额外字节。对于大型数据集(我有一些有大约5.3亿个观测值和众多字符串变量),这可以为导出的文件增加几千兆字节。

将文件加载到Stata后,Stata中的compress命令可以自动删除这些空字节并缩小文件,但对于大型数据集,PROC EXPORT会为文件添加如此多的额外字节我一直没有足够的内存来将数据集加载到Stata中。

有没有办法阻止SAS首先填充字符串变量?当我导出一个带有一个字符串变量的文件时(例如),我希望该变量存储为输出文件中的一个字符串变量。

2 个答案:

答案 0 :(得分:1)

这是使用现有功能的方法。

filename FT41F001 temp;
data _null_;
   file FT41F001;
   set test1;
   put 256*' ' @;
   __s=1;
   do while(1);
      length __name $32.;
      call vnext(__name);
      if missing(__name) or __name eq: '__' then leave;
      substr(_FILE_,__s) = vvaluex(__name);
      putlog _all_;
      __s = sum(__s,vformatwx(__name));
      end;
   _file_ = trim(_file_);
   put;
   format month f6.;
   run;

避免使用_FILE _;

data _null_;
   file FT41F001;
   set test1;
   __s=1;
   do while(1);
      length __name $32. __value $128 __w 8;
      call vnext(__name);
      if missing(__name) or __name eq: '__' then leave;
      __value = vvaluex(__name);
      __w = vformatwx(__name);
      put __value $varying128. __w @;
      end;
   put;
   format month f6.;
   run;

答案 1 :(得分:0)

如果您愿意接受平面文件答案,我会想出一种相当简单的方法来生成一个我认为具有您需要的属性的方法:

data test1;
    input cust_id   $ 1
          month       3-8
          category  $ 10-12 
          status    $ 14-14
;
datalines;
A 200003 ABC C
A 200004 DEF C
A 200006 XYZ 3
B 199910 SD  X
B 199912 D   C
;
run;

data _null_;
file "/folders/myfolders/test.txt";
set test1;
put @;
_FILE_ = cat(of _all_);
put;
run;

/* Print contents of the file to the log (for debugging only)*/
data _null_;
 infile "/folders/myfolders/test.txt";
 input;
 put _infile_;
run;

如果数据集中所有变量的总分配长度小于32767(数据步骤环境中cat函数的限制 - 低于200个字符的限制并且&##),这应该按原样工作39;仅当您使用cat创建未指定长度的变量时才应用。除此之外,您可能会遇到截断问题。发生这种情况时的解决方法是一次只有cat一起有限数量的变量 - 一个手动过程,但比根据所有变量的长度写出put语句要困难得多,并且取决于你的数据它实际上可能永远不会出现。

或者,您可以使用更复杂的宏路径,从vlength函数或dictionary.columns获取可变长度,并使用这些函数和变量名来构造所需的put语句(一个或多个)。