我有一个SAS数据集,我必须导出到.csv文件。我有以下两个相互矛盾的要求。
我必须使用分号作为.csv文件中的分隔符。
某些字符变量是从公式手动输入的字符串,因此它们可能包含分号。
我对上述方法的解决方法是转义分号或用逗号替换它。
tranwrd
整个数据集?我的尝试:
对于每个变量,对数据集中的变量使用tranwrd(.., ";", ",")
函数。更新数据集并循环遍历所有变量。然而,这对于甚至半大数据集来说自然是一种非常低效的方式,因为我必须为每个变量做一个datastep。它的代码非常难看,因为我必须通过几个步骤获得变量名称,但效率低下肯定会占上风。
data test;
input w $ c b d e $ f $;
datalines4;
Aaa;; 50 11 1 222 a;s
Bbb 35 12 2 250 qw
Comma, 75 13 3 foo zx
;;;;
run;
* Get the variable names;
proc contents data=test out=vars(keep=name type varnum) order=varnum noprint;
run;
* Sort by variable number;
proc sort data=vars;
by varnum;
run;
* Put variable names into a space-separated string;
proc sql noprint;
select compress(name)
into :name_list separated by ' '
from vars;
quit;
%let len = %sysfunc(countw(&name_list));
*Initialize loop dataset;
data a;
set test;
run;
%macro loop;
%do i = 1 %to &len;
%let j = %scan(&name_list,&i);
data a(rename=(v_&j = &j) drop=&j);
set a;
v_&j.=compress(tranwrd(&j,";",","));
run;
%end;
%mend;
%loop;
答案 0 :(得分:4)
我想我可能会为你的问题提供更优雅的解决方案:
data class;
set sashelp.class;
array vars [*] _character_;
do i = 1 to dim(vars);
vars[i] = compress(tranwrd(vars[i],"a","X"));
end;
drop i;
run;
您可以使用array
引用数据集中的所有字符列,然后循环遍历它们。
答案 1 :(得分:2)
对于其字段可以包含分隔符的csv文件,使用最广泛的标准是引用包含分隔符的字段,并将任何引号加倍。在SAS中,您可以使用put语句中的dlm
和dsd
选项自动执行此操作:
data test;
input w $ c b d e $ f $;
datalines4;
Aaa;; 50 11 1 222 a;s
Bbb" 35 12 2 250 qw
Comma, 75 13 3 foo zx
;;;;
run;
data _null_;
set test;
file "c:\temp\test.csv" dsd dlm=';';
put (_ALL_) (&);
run;
这导致以下以分号分隔的csv(减去标题行,但这是一个单独的问题):
"Aaa;;";50;11;1;222;"a;s"
"Bbb""";35;12;2;250;qw
Comma,;75;13;3;foo;zx
抱歉,在我发布此消息之前,我们没有注意到您对该解决方法的评论。如果有人发现它有用,我会留在这里。
答案 2 :(得分:0)
引用格式正确的分隔文件中的字段。 PROC EXPORT会这样做。无需更改数据。
data test;
input w $ c b d e $ f $;
datalines4;
Aaa;; 50 11 1 222 a;s
Bbb 35 12 2 250 qw
Comma, 75 13 3 foo zx
;;;;
run;
filename FT45F001 temp;
proc export data=test outfile=FT45F001 dbms=csv;
delimiter=';';
run;
data _null_;
infile FT45F001;
input;
list;
run;
proc import replace datafile=FT45F001 dbms=csv out=test2;
delimiter=';';
run;
proc print;
run;
proc compare base=test compare=test2;
run;