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