我正在尝试编写一个SAS宏,它将几个csv文件循环到库中。不幸的是,我在完成这项工作方面并不是很成功。这是我到目前为止:
%let list = "cat and dogs" "monkeys" "humans";
%macro loop;
%do _i=1 %to %sysfunc(countw(&list.));
%let read_list = %scan(&list., &i.)
proc import datafile="[path] - &read_list."
out=displayfile&read_list. dbms=csv replace;
run;
%end;
%mend;
更新:
我将我的代码更新为
%macro read;
%let list = (humans, cats and dogs) ;
%do i= 1 %to 7;
%let fnames = %scan(&list., &i.);
proc import datafile= "path- &fnames..csv"
out=&fnames. dbms=csv replace;
run;
%end;
%mend;
这适用于以“human”结尾的文件,但不适用于由于字符串中的空格而以“cats and dogs”结尾的文件。有解决方法吗?
我建议在列表中使用不同的分隔符。像|
这样的东西不能成为文件名的一部分。
%let list =cat and dogs|monkeys|humans;
... %sysfunc(countw(&list,|)) ...
... %scan(&list,&i,|) ...
另一个问题是您需要确保生成有效的SAS数据集名称。最好使用数据集名称中的数字,并将字符串用作标签的一部分。
out=csvfile&i (label="&fnames")
你的两个例子的问题是你告诉%scan()
函数(和countw()
函数)使用它们的默认分隔符字符集。这些字符在ASCII系统上是哪个:
blank ! $ % & ( ) * + , - . / ; < ^ ¦
因此,在您的第一个示例中,字符串中的唯一分隔符是空格,因此字符串中的单词是:
"cat
and
dogs"
"monkeys"
"humans"
注意引号是%scan()
发现的单词的一部分,因为它们不是分隔符。因此,即使像"humans"
这样的值也无法正常运行,因为它们包含了额外的引号字符。将"cat and dogs"
分成三个单词会增加引号不均衡的额外问题。
在你的第二个你还有另外三个字符,(,)
,将被视为分隔符所以单词是:
humans
cats
and
dogs
如果你真的想处理一个以空格分隔的带引号的字符串列表,那么告诉%scan()
使用blank作为分隔符并添加q
修饰符以允许带引号的字符串。您可能还需要使用dequote()
函数来删除值周围的引号。
试试这个测试程序,看看如何做到这一点。
%macro test(list);
%local i word ;
%do i=1 %to %sysfunc(countw(&list,%str( ),q));
%let word=%sysfunc(dequote(%qscan(&list,&i,%str( ),q)));
%put i=&i word=&word;
%end;
%mend test;
%test("cat and dogs" "monkeys" "humans")
我同意最后的答案。数据集名称必须以字母或下划线开头,后续字符可以是字母,下划线或数字。名单之一是猫和狗。我想当你运行代码时,你会在日志中看到错误。但我在proc导入数据步骤中运行带有注释的最后一个代码,并且如下所示。
%macro read;
%let list = (humans, cats and dogs);
%do i= 1 %to 7;
%let fnames = %scan(&list., &i.);
/*
proc import datafile= "path- &fnames..csv"
out=&fnames. dbms=csv replace;
run;
*/
%put &fnames;
%end;
%mend;
%read;
SAS Log显示:
人类
猫
和
小狗