Чтение нескольких файлов txt из разных папок в набор данных SAS

У меня следующая проблема, и я действительно не знаю, с чего начать. У меня есть папка с именем ALL, и внутри этой папки есть подпапки с названиями, равными дате их создания в формате ДД-ММ-ГГГГ. Есть папка на каждый день, т.е. без пропущенных дней. Внутри каждой из этих папок есть множество файлов txt. Я хотел бы прочитать по одному из этих текстовых файлов из каждой папки с датами. Этот файл будет иметь соглашение об именах thedata_, за которым следует случайный ряд чисел.

Так, например, если в папке ALL есть 3 папки с датами, я хотел бы прочитать 3 отдельных текстовых файла thedata_ в 1 окончательном файле SAS. И впоследствии каждый день добавляется новая папка, я хочу добавить файл thedata_ из этой папки в существующий файл SAS, а не запускать сценарий с нуля.


person astel    schedule 27.05.2021    source источник
comment
Сначала создайте список файлов. Найдите здесь или на сайте community.sas.com программы, которые будут сканировать каталог и перечислять все файлы. Затем вы фильтруете этот список для файлов, которые хотите прочитать, на основе ваших правил, используя шаг данных. Это оставит вам список файлов для импорта. Параметр filevar в операторе INFILE позволяет динамически изменять входные файлы и читать сразу из всех файлов. В документации есть примерный пример.   -  person Reeza    schedule 28.05.2021


Ответы (1)


Вот одно решение. При этом используются функции SAS для чтения и заполнения набора данных, который читает каждый файл в каждой папке, поэтому вам не нужно включать команды x. Вы можете сохранить каждый из них в макропеременной, а затем перебрать и прочитать каждый файл, как захотите. Вы можете изменить это для работы с опцией filevar.

filename all "Directory/ALL";

data myfiles;
    length folder_name 
           file_name  
           file
           folder_path $5000.
    ;

    /* Folder delimiter */
    if("&sysscp." = "WIN") then SLASH = '\';
        else SLASH = '/';

    /* Open the ALL directory */
    did = dopen("all");

    /* If it was successful, continue */
    if(did) then do;  

        /* Iterate through all subfolders in ALL */
        do i = 1 to dnum(did);

            /* Get the subfolder name and full path */
            folder_name = dread(did, i);
            folder_path = cats(pathname('all'), SLASH, folder_name);

            /* Assign a filename statement to the subfolder */
            rc = filename('sub', folder_path);
            
            /* Give the sub-folder a a directory ID */
            did2 = dopen('sub');

            /* Open the subfolder and read all the .txt files within it */
            if(did2) then do;
                do j = 1 to dnum(did2);

                    file_name = dread(did2, j);
                    file_ext  = scan(file_name, -1, '.');
                    file      = cats(folder_path, SLASH, file_name);
                    
                    /* Save file name only if the expected value is found */
                    if(upcase(file_name) =: "THEDATA_" AND upcase(file_ext) = "TXT") then do;
                        nfiles+1;
                        call symputx(cats('file', nfiles), file); /* Save each file to a macro variable named file1, file2, etc. */
                        output;
                    end;
                end;
            end;

            /* Close the subfolder and move on to the next one */
            rc = dclose(did2);
        end;

    end;

    rc = dclose(did);

    /* Save the total number of files we found to a macro variable */
    call symputx('nFiles', nFiles);

    keep file file_name folder_name folder_path;
run;

/* Read all the files */
%macro readFiles;
    %do i = 1 %to &nFiles.;
        proc import 
            file = "&&file&i."
            out  =  _thedata_&i.
            dbms =  csv
            replace;
            guessingrows=max;
        run;
    %end;

    /* Put all the files together */
    data thedata;
        set _thedata_:;
    run;

    proc datasets lib=work nolist;
        delete _thedata_:;
    quit;
%mend;
%readFiles;
person Stu Sztukowski    schedule 28.05.2021