Как импортировать CSV-файлы с помощью макросов в SAS? - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь написать макрос 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; 

Это работает для файлов, оканчивающихся на "люди", но не для файлов, оканчивающихся на "кошки и собаки" из-за пробела в строке. Есть ли обходной путь?

Ответы [ 2 ]

0 голосов
/ 16 сентября 2018

Я согласен с последним ответом.Имена набора данных должны начинаться с буквы или подчеркивания, последующие символы могут быть буквой, подчеркиванием или цифрами.Одно из названий списка - кошки и собаки.Я думаю, что когда вы запустите код, вы увидите ошибку в журнале.Но я запускаю последний код с комментариями в шаге импорта данных процесса, и он соответствует приведенному ниже.

%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 показывает это:

человек

кошка

и

собаки

0 голосов
/ 15 сентября 2018

Я бы рекомендовал использовать другой разделитель в вашем списке. Нечто подобное |, которое не может быть частью имени файла.

%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")
...