将观测值从SAS数据集读入数组

将观测值从SAS数据集读入数组,sas,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

这个问题与大型机上的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

如果我正确理解您的需求,您可以在proc转置的帮助下得到您想要的结果

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;

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;
我已经“增强”了答案,以允许起始数据集中的行数可变

此外,您还提到了在大型机上运行:唯一需要的更改应该是操作系统特定的文件语句


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

我正要发布这篇文章,鲍勃发布了他的;我将继续并张贴它无论如何,因为它显示了一些不同的概念,从他的。如果您不需要中间数据集,并且拥有相当大的数据集,那么您的最佳选择可能是两者的组合

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;

您的意思是要创建三个SAS阵列,每个阵列有六个元素?SAS“数组”不是持久的;它们只是数据步编程的一部分。定义这三个数组之后,您想做什么?是的,这正是我的意思。我打算将SAS数据集写入CSV文件,该文件将由小型web服务器上的图形工具读取。CSV文件必须具有“垂直”数据(我将编辑原始问题以展示这一点)。我的想法是使用PUT语句写出数据,我认为数组会使这更易于管理,如果我错了,请纠正我。谢谢你花时间来帮助我。只是一个旁注——“垂直”并不是你在这里真正的意思;例如,请参阅“垂直”的含义。您的第一个数组的问题是您正在混合put方法-用法:MMYYS。如果你想让它正常工作(注意冒号)。顺便说一下,Bob,假设你有9.2+(我相信),你不必再使用分隔符了;您可以将其编写为:
procsql;选择x到:从数据集中修剪xvar;退出
并获得修剪结果。(Notrim与之相反,与分隔符一起使用可获得未修剪的分隔结果。)感谢您的帮助Natsja,不幸的是,我无法在大型机环境中使用proc export。我又添加了两种可能的解决方案。也许其中一个会有帮助?在尝试了你的第2个解决方案后,这就是我最终使用的解决方案。非常感谢。2很聪明,但我不推荐使用它。您不应该将数据放入宏变量中。这不仅不是他们的目的(有点像用咖啡杯把汽油带到你的车上),而且还有很多潜在的危险;无效字符、变量长度限制等。如果没有其他好方法,这可能没问题,但这个问题有很多干净安全的解决方案(如1和3,或Bob/I的解决方案)。是的,你真的可以使用宏变量,如果你给它们加上一些线,它们就会改变,或者你会忘记这一切是怎么安排的。乔恩,我还是很高兴你喜欢第二种解决方案。希望您的问题不会有任何问题。我最终使用了Bellevuebob给出的建议,但我可以看到您在这方面也提供了有用的意见。非常感谢您抽出时间来帮助我,非常感谢。