loops - 如何在 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”结尾的文件,因为字符串中有空格。有解决方法吗?
解决方案
我建议在您的列表中使用不同的分隔符。类似的东西|
不能是文件名的一部分。
%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")
推荐阅读
- sql - 使用派生可插入的浮点数
- azure - 如何在 Azure 中使用 Webjob 调用 WebApp 中的方法
- python - 如何创建一个从列表中获取值并放入方法并收集结果的函数?
- c# - 如何使用最新的 MongoDB C# 驱动程序根据多个条件删除复杂数组对象的嵌套数组中的元素?
- python - 在 python 函数中,我是否需要预先分配一个有条件地出现在 if 下的值?
- api - Symfony API 平台 - 嵌入插入
- php - Laravel Eloquent 用户表和状态表之间的关系,用户表中有 states_id
- pdf - 连接pdf并添加目录
- c# - 使用多个上下文 .Net 核心
- php - 有什么方法可以从 shell 脚本到网站的实时输出?