高效地将SAS数据集转换为CSV
谁能告诉我以编程方式将SAS数据集转换为CSV文件的最快方法是什么。我知道我可以使用数据步骤并输出到文件等,但这是唯一的方法吗 谢谢,高效地将SAS数据集转换为CSV,csv,sas,Csv,Sas,谁能告诉我以编程方式将SAS数据集转换为CSV文件的最快方法是什么。我知道我可以使用数据步骤并输出到文件等,但这是唯一的方法吗 谢谢, 阿德南。这是什么 proc export data=sashelp.class outfile='c:\temp\sashelp class.csv' dbms=csv replace; run; 创建SAS数据集的.CSV文件的5种不同方法 请参考这里的答案,这里有许多创建csv的方法,但不一定是这些方法的效率。我创建了一个样本数据集
阿德南。这是什么
proc export data=sashelp.class
outfile='c:\temp\sashelp class.csv'
dbms=csv
replace;
run;
创建SAS数据集的.CSV文件的5种不同方法
请参考这里的答案,这里有许多创建csv的方法,但不一定是这些方法的效率。我创建了一个样本数据集(
temp
),其中包含100000行和五列,以测试和比较将sas数据集导出到名为temp.csv
的csv的方法
第一种方法:导出过程。运行时间:0.43秒
PROC EXPORT data=temp
outfile="temp.csv" dbms=csv replace;
ODS csv file="temp.csv";
PROC PRINT data=temp noobs;
RUN;
ods csv close;
DATA _null_;
FILE "temp.csv ";
SET temp;
put (_all_) (',');
RUN;
运行时间快,简单,在选择其他选项时具有机箱内的灵活性。尽管如此,它并不是最适合定制的
第二种方法:ODS和打印程序。运行时间:14.09秒
PROC EXPORT data=temp
outfile="temp.csv" dbms=csv replace;
ODS csv file="temp.csv";
PROC PRINT data=temp noobs;
RUN;
ods csv close;
DATA _null_;
FILE "temp.csv ";
SET temp;
put (_all_) (',');
RUN;
对于大多数用例,这种方法是三种方法中最差的一种,尽管有一些特殊用例。这对于以前编写的过程的临时输出是很好的,特别是如果您希望输出保持在lst文件中(如果不是太大的话)。当您希望将另一个过程(例如,复杂的表格
)转换为文件而无需进一步操作时,它也可能很有用。如果您不需要在lst文件中打印输出,请关闭您的列表(ods listing close
),否则这将花费非常长的时间
第三种方法:文件语句。运行时间:0.06秒
PROC EXPORT data=temp
outfile="temp.csv" dbms=csv replace;
ODS csv file="temp.csv";
PROC PRINT data=temp noobs;
RUN;
ods csv close;
DATA _null_;
FILE "temp.csv ";
SET temp;
put (_all_) (',');
RUN;
虽然这种方法的性能还不错,但它不直观,看起来很混乱。但是,如上所述,您可以更好地控制输出,并且它的运行时间是所有输出中最快的。Modifieddata\u NULL
approach
这里是对data\u NULL\u
方法的修改,该方法在第一个数据步骤中将头行写入文件,然后在第二个数据步骤中继续使用数据行写入同一文件
%macro outputCSV(dataset,file);
data _NULL_;
file "&file." dlm=',' dsd;
length header $ 2000;
dsid=open("&dataset.","i");
num=attrn(dsid,"nvars");
do i=1 to num;
header = trim(left(coalescec(varlabel(dsid,i),varname(dsid,i))));
put header @;
end;
rc=close(dsid);
run;
data _NULL_;
set &dataset.;
file "&file." mod dlm=',' dsd;
put (_all_) (+0);
run;
%mend;
%outputCSV(sashelp.class,~/temp4.csv)
它可以使用keep
和drop
数据集选项(令人惊讶),但不幸的是,当使用open()
打开数据集时,nvars
属性尊重keep
或drop
之后的新变量数,但是varlabel
和varname
函数仍然使用它们的varnum
查找变量
在下面的示例中,仅从SASHELP.CLASS
中提取Name
(varnum=1)和Height
(varnum=4),因为只保留了两个变量,nvars
是2,但是如果我们在循环中以num作为上限进行迭代,我们会遗漏Height
,因为它的varnum
是4:
62 data _NULL_;
63 dsid = open("sashelp.class (keep=name height)","i");
64 num = attrn(dsid,"nvars");
65 do i=1 to 5;
66 vname = varname(dsid,i);
67 put i= vname= num=;
68 end;
69 run;
i=1 vname=Name num=2
NOTE: Argument 2 to function VARNAME(1,2) at line 66 column 13 is invalid.
i=2 vname= num=2
NOTE: Argument 2 to function VARNAME(1,3) at line 66 column 13 is invalid.
i=3 vname= num=2
i=4 vname=Height num=2
NOTE: Argument 2 to function VARNAME(1,5) at line 66 column 13 is invalid.
i=5 vname= num=2
dsid=1 num=2 i=6 vname= _ERROR_=1 _N_=1
有两种选择:
- 通过剥离第一次传递的数据集选项,提取真实的
值nvars
- 使用一个非常高的数字,而不是
,尽管这只会导致日志中出现大量num
注释“无效”
open
函数:
%macro outputCSV(dataset,file);
data _NULL_;
file "&file." dlm=',' dsd;
length header $ 2000;
dsid=open("%SCAN(&dataset.,1,()","i");
num=attrn(dsid,"nvars");
rc=close(dsid);
dsid=open("&dataset.","i");
do i=1 to num;
header = trim(left(coalescec(varlabel(dsid,i),varname(dsid,i))));
if _error_ = 0 then put header @;
_error_ = 0;
end;
rc=close(dsid);
run;
data _NULL_;
set &dataset.;
file "&file." mod dlm=',' dsd;
put (_all_) (+0);
run;
%mend;
%outputCSV(sashelp.class (keep=name height),~/temp4.csv)
在写出所有这些之后,在大多数情况下使用
PROC EXPORT
,或者在变量不多的情况下显式列出变量可能是有意义的。这只是说明了可以做些什么。是的,这是我们讨论过的选项之一。您知道它与数据步骤方法相比是如何伸缩的吗?根据日志,proc export生成一个数据空步骤来写出文本文件。所以我想从一开始就使用数据步骤在cpu时间方面会更有效率。数据步骤可以让您更好地控制输出。我可能最终会使用数据null,因为我想控制导出哪些列,以及格式化/不格式化列值等。仅供参考,我注意到在运行SAS程序(在批处理模式下)时必须使用-noterminal选项使用proc export创建csv或其他平面文件的。您错过了%ds2csv
宏:警告:data null方法不会在.csv的第一行输出变量名,这可能是个问题。您应该在file语句中使用DSD选项,而不是手动写入分隔符。否则,您可能无法获得可解密的文件。请注意,添加一点代码来编写标题行并不难。@Tom我觉得有另一个答案在路上…?不需要使用那些旧的SCL函数。只需使用PROC TRANSPOSE按顺序创建一个具有变量名的数据集proc transpose data=have(obs=0)out=name;var u all u;运行代码>然后使用简单的数据步骤写入标题行。然后将MOD选项添加到数据步骤中写入实际数据行的file语句中。是的,很好的调用,尝试使用array\u character\uu
及其对应项进行类似操作,但无法按顺序显示列。谢谢@mjsqu!这是一个很好的答案-我将您的代码合并到我们的宏库中,我希望这样可以: