将SAS数据集中的观察结果读入数组

时间:2013-05-22 11:24:31

标签: sas

这个问题与大型机上的SAS有关,尽管我认为它在这种情况下并没有什么不同。

我有以下SAS数据集:

Obs     DATO    T_ALLOC    T_FRESP

 1     19328      647        1804 
 2     19359      654        1797 
 3     19390      662        1789 
 4     19418      676        1774 
 5     19449      636        1815 
 6     19479      698        1753 

我的目标是将3个变量的所有6个观察值(我希望我在这里使用正确的术语)放入单独的数组中。

我已经努力阅读有关使用数组的工作,但出于某种原因,这个特定问题的解决方案让我望而却步。

如果有人愿意伸出援助之手,我将不胜感激。即使是包含我正在寻找的答案的文档的链接也会非常有用。

如果我的解释不清楚,请告诉我,我将提供所需的任何其他信息。

提前致谢。

编辑 - >

我的最终CSV应该与此类似:

Datoer,01/2013,02/2013,03/2013,04/2013,05/2013,06/2013,07/2013,08/2013,09/2013,10/2013
Freespace,800,1000,1243,1387,1457,1562,1620,1700,1800,1900
Allokeret,1000,1200,1456,1689,1784,1865,1930,2000,2100,2200

3 个答案:

答案 0 :(得分:4)

如果我理解你的需要,你可以在proc transpose的帮助下得到你想要的结果。

proc transpose data = datain out = dataout;
    var DATO T_ALLOC T_FRESP;
run;

proc export data=dataout
    outfile='xxxxx\tmp.csv'
    dbms=csv
    replace;
run;

使用SQL的另一个想法。

proc sql noprint;
    select DATO into :dato separated by ',' from datain;
    select T_ALLOC into :talloc separated by ',' from datain;
    select T_FRESP into :tfresp separated by ',' from datain;
quit;

data _NULL_;
    file 'xxxxx\tmp.csv';
    put "var1,&dato";
    put "var2,&talloc";
    put "var3,&tfresp";
run;

另一个有数组。

data _NULL_;
    set datain nobs = nobs;
    array data DATO T_ALLOC T_FRESP;
    format t1-t3 $50.;
    retain t1-t3;
    array t[3] $;
    do i = 1 to dim(t);
        if _N_ = 1 then t[i] = put(data[i], 8.);
            else t[i] = compress(t[i] || ',' || put(data[i], 8.));
    end;
    if _N_ = nobs;
    file 'xxxxx\tmp.csv';
    put "var1," t1;
    put "var2," t2;
    put "var3," t3;
run;

答案 1 :(得分:2)

Natsja的答案很好(只要你的所有值都是数字)。但是,既然您询问了数组,那么使用数组和传统的数据步骤处理这是一个更冗长的答案:

data have;
   input DATO T_ALLOC T_FRESP;
   datalines;
19328      647        1804 
19359      654        1797 
19390      662        1789 
19418      676        1774 
19449      636        1815 
19479      698        1753 
run;

/* Find number of records in data set */
/* The "separated by" clause is a trick to trim leading blanks */
proc sql noprint;
   select count(*) into :num_recs separated by ','
   from have;
quit;

data _null_;
   /* Define variables wanted */
   /* These could be defined as _TEMPORARY_ arrays but I left them as */
   /* creating actual variables for illustration.                     */
   array a(&num_recs) DATO1-DATO&num_recs;
   array b(&num_recs) T_ALLOC1-T_ALLOC&num_recs;
   array c(&num_recs) T_FRESP1-T_FRESP&num_recs;

   /* Load the arrays */
   do while(not eof);
      set have end=eof;
      _i_ + 1;
      a(_i_) = DATO;
      b(_i_) = T_ALLOC;
      c(_i_) = T_FRESP;
      end;

   /* Create the CSV file with three records */
   file 'c:\temp\wanted.csv' dlm=',';

   length header $10;
   header = 'Datoer';
   put header @;
   do _i_ = 1 to dim(a);
      put a(_i_) :mmyys. @;
      end;
   put;
   header = 'Freespace';   
   put header @;
   do _i_ = 1 to dim(b);
      put b(_i_) @;
      end;
   put;
   header = 'Allokeret,';   
   put header @;
   do _i_ = 1 to dim(c);
      put c(_i_) @;
      end;
   put;

   /* Explicitly stop the data step in this example */
   stop;
run;

我已经“增强”了答案,允许在起始数据集中包含可变数量的行。

另外,您提到在大型机上运行:所需的唯一更改应该是特定于操作系统的FILE语句。

更新:根据Joe的有用评论修改了答案。

答案 2 :(得分:0)

当鲍勃发布他的时候,我正准备发布这个帖子;我会继续发布它,因为它显示了他的几个不同的概念。如果您不想要中间数据集,并且拥有相当大的数据集,那么您最好的选择可能是两者的组合。

data have;
input DATO    T_ALLOC    T_FRESP;
datalines;
19328      647        1804 
19359      654        1797 
19390      662        1789 
19418      676        1774 
19449      636        1815 
19479      698        1753 
;;;;
run;

*Get the array parameter;
proc sql noprint;
select count(1) into :reccount from have ;
quit;

data want;
length varname $8;
*Define the intermediate arrays as _temporary_ so they are stored in memory only;
array datos[&reccount] _temporary_;
array tallocs[&reccount] _temporary_;
array tfresps[&reccount] _temporary_;
*The final array that will be written out is stored in physical disk space;
*If you write this out to a file directly this array can be skipped;
array final_vars[&reccount];

do _t = 1 to &reccount;
 set have;
 datos[_t]=dato;
 tallocs[_t]=t_alloc;
 tfresps[_t]=t_fresp;
end;

*If I were doing this I would write a macro to do this part, as it is the same thing three times;
varname="DATO";
do _t = 1 to &reccount;
 final_vars[_t]=datos[_t];
end;
output;

varname="T_ALLOC";
do _t = 1 to &reccount;
 final_vars[_t]=tallocs[_t];
end;
output;

varname="T_FRESP";
do _t = 1 to &reccount;
 final_vars[_t]=tfresps[_t];
end;
output;

keep final_vars: varname;
run;