Код SAS для транспонирования и переименования переменных в определенном столбце перед импортом - PullRequest
0 голосов
/ 01 мая 2019

Я использую приведенный ниже макрос для импорта нескольких CSV-файлов, который прекрасно работает.Однако я пытаюсь переместить столбцы 3 и 6 в моем наборе данных из столбцов в строки перед импортом.Затем я хотел бы переименовать эти столбцы как дату и исследование соответственно.

(Прямо сейчас, например, каждый файл имеет другую дату в столбце 3 в качестве имени столбца, которое я хотел бы перенести в строку и датьстолбец с новым именем, т.е. с такой датой, чтобы при установке всех импортированных файлов один под другим все было в столбце с именем date)

. Я не знал бы заранее, какой столбец 3 будет назван вкаждый из моих файлов.Так, например, в файле 1 его можно назвать XYZ и YYX в файле 2, и я хочу назвать оба date, а также вместо них ввести XYZ и YYX в строку.Примеры приведены ниже:

В файле 1:

| Pt | Rt | XYZ |
|----|----|------|
| 1  | 2  |       |

В файле 2:

| Pt | Rt | YYZ |
|----|----|------|
| 3  | 4  |       |

Результат должен выглядеть следующим образом:

| Pt | Rt | date |
|----|----|-------|
| 1  | 2  | XYZ |
| 3  | 4  | YYX |

Код:

%*Creates a list of all files in the DIR directory with the specified extension (EXT);

%macro list_files(dir,ext);

      %local filrf rc did memcnt name i;

      %let rc=%sysfunc(filename(filrf,&dir));

      %let did=%sysfunc(dopen(&filrf));



      %if &did eq 0 %then

            %do;

                  %put Directory &dir cannot be open or does not exist;



                  %return;

            %end;



      %do i = 1 %to %sysfunc(dnum(&did));

            %let name=%qsysfunc(dread(&did,&i));



            %if %qupcase(%qscan(&name,-1,.)) = %upcase(&ext) %then

                  %do;

                        %put &dir\&name;

                        %let file_name =  %qscan(&name,1,.);

                        %put &file_name;



                        data _tmp;

                              length dir $512 name $100;

                              dir=symget("dir");

                              name=symget("name");

                              path = catx('\',dir,name);

                              the_name = substr(name,1,find(name,'.')-1);

                        run;



                        proc append base=list data=_tmp force;

                        run;



                        quit;



                        proc sql;

                              drop table _tmp;

                        quit;



                  %end;

            %else %if %qscan(&name,2,.) = %then

                  %do;

                        %list_files(&dir\&name,&ext)

                  %end;

      %end;



      %let rc=%sysfunc(dclose(&did));

      %let rc=%sysfunc(filename(filrf));

%mend list_files;



%*Macro to import a single file, using the path, filename and an output dataset name must be specified;

%macro import_file(path, file_name, dataset_name );



      proc import

            datafile="&path.\&file_name."

            dbms=csv

            out=&dataset_name replace;

      run;



%mend;



*Create the list of files, in this case all CSV files;

%list_files(C:\Users\baidw002\Documents\1 BCH-LJAF\Real data transfer (BCH to UAB)\CGM\cgmtestfiles\machine\csv, csv);



%*Call macro once for each entry in the list table created from the %list_files() macro;

data _null_;

      set list;

      string = catt('%import_file(', dir, ', ',  name,', ', catt('test', put(_n_, z2.)), ');');

      call execute (string);

run;

Код от: https://github.com/statgeek/SAS-Tutorials/blob/master/Import_all_files_one_type

Edit1: Как предлагается в первом комментарии.

Edit2: добавлена ​​ссылка на источник кода.

1 Ответ

1 голос
/ 01 мая 2019

Почему бы просто не сделать все это за один шаг данных?SAS может читать файлы CSV напрямую, не используя PROC IMPORT.

Используйте подстановочный знак в имени файла, чтобы прочитать все файлы одновременно.Когда вы находитесь в первой строке файла, прочитайте DATE из строки заголовка.

%let path=C:\Users\baidw002\Documents\1 BCH-LJAF\Real data transfer (BCH to UAB)\CGM\cgmtestfiles\machine\csv;
data want ;
  length pt 8 rt 8 date 8 ;
  informat date anydtdte.;
  format date yymmdd10.;

  length dummy $1 fname $256;
  infile "&path/*.csv" filename=fname truncover dsd ;
  input @;
  if fname ne lag(fname) then do;
    input 2*dummy date ;
    retain date;
  end;
  input pt rt ;
  drop dummy;
run;

Так что, если я создам несколько фиктивных файлов:

%let path=%sysfunc(pathname(work));
data _null_;
  file "&path/test1.csv";
  put 'pt,rt,3/4/19' / '1,2';
  file "&path/test2.csv";
  put 'pt,rt,4/5/19' / '3,4';
run;

я получу этот результат:

Obs    pt    rt          date

 1      1     2    2019-03-04
 2      3     4    2019-04-05
...