我使用SAS 9.4。
我有一个表名表,有两列:libname和memname,这是库名和表名,例如打击:
libname | memname
lib1 | table1
lib2 | table2
对于每条记录,我想验证列LIKE'%CLI%'是否具有字符串类型并且仅包含数字。每个表最多包含一个满足这些条件的列。
最后,我想将找到的列的名称作为新列添加到表名表中:
libname | memname | colname
lib1 | table1 | client
lib2 | table2 | cli_num
非常感谢您的帮助。
答案 0 :(得分:2)
可以在不实际打开数据集的情况下检查存在性和类型。但是我们需要打开它们以检查值是否均为数字。这是您可以使用的循环构造,包括相关测试和示例数据。
/* CLI exists, contains only digits*/
data ex1;
input other $ CLI $;
datalines;
x 1234
x 5787
;
/* CLI exists, doesn't contains only digits*/
data ex2;
input other $ CLI $;
datalines;
x 123a
x 5787
;
/* CLI exists, isn't character*/
data ex3;
input other $ CLI;
datalines;
x 1234
x 5787
;
/* CLI doesn't exist*/
data ex4;
input other $ other2;
datalines;
x 1234
x 5787
;
/* Makes a table of the datasets*/
data tableoftables;
input libname $ memname $;
datalines;
work ex1
work ex2
work ex3
work ex4
;
%macro do_stuff(indata=);
/* A data set to collect test results and present them to user.*/
data out;
set &indata;
length exists $3 type $9. alldigits $3.;
run;
/* Put libname and data set names into macro variables*/
data _null_;
set &indata;
call symput(cat('libname', _n_), libname);
call symput(cat('memname', _n_), memname);
run;
/* Find the number of datasets to loop through*/
proc sql noprint;
select count(*)
into :rows
from &indata;
/* Loop over data sets*/
%do i=1 %to &rows;
/*If CLI was in a specific place, you could use varnum, like here: https://communities.sas.com/message/154973. To use like, it's easier to go through proc contents*/
/* Create data ser with variables*/
proc contents noprint data=&&libname&i...&&memname&i out=row&i;
run;
/* Test 1: Is variable in file*/
/* Infile is initiated as 0, but turns to 1 if there is at least one variable like '%CLI%'. Type and name are collected*/
%let infile=0;
data test&i;
set row&i;
where name like '%CLI%';
call symput('infile', 1);
call symput('type', type);
call symput('name', name);
run;
/* Test 2: Is variable character*/
%let typetext=-;
%if &infile=1 %then %do;
%if &type=2 %then %let typetext=Character;
%else %if &type=1 %then %let typetext=Numeric;
%end;
/* Test 3: Does variable only contain digits*/
%let alldigits=-;
data test3&i;
set &&libname&i...&&memname&i end=eof;
retain test;
if _n_=1 then test=0;
notdigit=notdigit(strip(&name));
test+notdigit;
if eof then do;
if test=0 then call symput('alldigits', "YES");
else call symput('alldigits', "NO");
end;
run;
data out;
set out;
if _n_=&i then do;
if &infile=1 then exists="YES";
else exists="NO";
type="&typetext";
alldigits="&alldigits";
end;
run;
%end;
proc print data=out;
run;
%mend;
%do_stuff(indata=tableoftables)