导入前在特定列中转置和重命名变量的 SAS 代码
SAS code to transpose and rename variables in a specific column before importing
我正在使用下面提供的宏导入几个效果很好的 csv 文件。然而,在导入之前,我正在努力将数据集中的第 3 列和第 6 列从列转置为行。然后我想将这些列分别重命名为 date 和 study。
(例如,现在每个文件在第 3 列中都有一个不同的日期作为列名,我想将其放到该行并为该列指定一个新名称,即日期,这样当我设置所有导入的文件一个接一个地放在名为 date
)
的列中
我事先不知道我的每个文件中的第 3 列是什么。因此,例如,在文件 1 中,它可以在文件 2 中命名为 XYZ
和 YYX
,我想同时命名为 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 2 name 0;
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 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: 添加了 link 到代码源。
为什么不只用一个数据步骤完成所有事情? SAS 无需使用 PROC IMPORT 即可直接读取 CSV 文件。
在文件名中使用通配符一次读取所有文件。
当您位于文件的第一行时,请从 header 行读取日期。
%let path=C:\Users\baidw002\Documents 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 fname 6;
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
我正在使用下面提供的宏导入几个效果很好的 csv 文件。然而,在导入之前,我正在努力将数据集中的第 3 列和第 6 列从列转置为行。然后我想将这些列分别重命名为 date 和 study。
(例如,现在每个文件在第 3 列中都有一个不同的日期作为列名,我想将其放到该行并为该列指定一个新名称,即日期,这样当我设置所有导入的文件一个接一个地放在名为 date
)
我事先不知道我的每个文件中的第 3 列是什么。因此,例如,在文件 1 中,它可以在文件 2 中命名为 XYZ
和 YYX
,我想同时命名为 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 2 name 0;
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 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: 添加了 link 到代码源。
为什么不只用一个数据步骤完成所有事情? SAS 无需使用 PROC IMPORT 即可直接读取 CSV 文件。
在文件名中使用通配符一次读取所有文件。 当您位于文件的第一行时,请从 header 行读取日期。
%let path=C:\Users\baidw002\Documents 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 fname 6;
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