将观测值从SAS数据集读入数组
这个问题与大型机上的SAS有关,尽管我认为这在这种情况下没有什么区别 我有以下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
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给出的建议,但我可以看到您在这方面也提供了有用的意见。非常感谢您抽出时间来帮助我,非常感谢。