首页 > 解决方案 > 如何在 sas 中使用宏循环导入 csv 文件?

问题描述

我正在尝试编写一个 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; 

这适用于以“humans”结尾的文件,但不适用于以“cats and dogs”结尾的文件,因为字符串中有空格。有解决方法吗?

标签: loopsimportmacrossas

解决方案


我建议在您的列表中使用不同的分隔符。类似的东西|不能是文件名的一部分。

%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()使用空白作为分隔符并添加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")

推荐阅读