Skip to content

Commit

Permalink
feat: adding MATCH parameter to mp_searchcols.sas to enable fuzzy mat…
Browse files Browse the repository at this point in the history
…ching on columns. Closes #14
  • Loading branch information
Allan Bowe committed May 13, 2021
1 parent 51ddd9c commit c6b6536
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 8 deletions.
41 changes: 36 additions & 5 deletions all.sas
Expand Up @@ -2945,7 +2945,7 @@ run;
proc sql;
create table data1 as select * from sashelp.class;
create view view2 as select * from sashelp.class;
%mp_dropmembers(libref=WORK, list=data1 view2)
%mp_dropmembers(data1 view2, libref=WORK)


<h4> SAS Macros </h4>
Expand Down Expand Up @@ -5729,14 +5729,23 @@ run;

%mp_searchcols(libs=sashelp work, cols=name sex age)

@param libs=
@param libs=(SASHELP) Space separated list of libraries to search for columns
@param cols= Space separated list of column names to search for (not case
sensitive)
@param outds=(mp_searchcols) the table to create with the results. Will have
one line per table match.
@param match=(ANY) The match type. Valid values:
@li ANY - The table contains at least one of the columns
@li WILD - The table contains a column with a name that partially matches

@version 9.2
@author Allan Bowe
**/

%macro mp_searchcols(libs=sashelp
,cols=
,outds=mp_searchcols
,match=ANY
)/*/STORE SOURCE*/;

%put &sysmacroname process began at %sysfunc(datetime(),datetime19.);
Expand All @@ -5758,8 +5767,10 @@ create table _data_ as
%end;
order by 1,2,3;

%local tempds;
%let tempds=&syslast;
data &outds;
set &syslast;
set &tempds;
length cols matchcols $32767;
cols=upcase(symget('cols'));
colcount=countw(cols);
Expand All @@ -5773,10 +5784,29 @@ data &outds;
retain matchcols;
matchcols='';
end;
%if &match=ANY %then %do;
if findw(cols,name,,'spit') then do;
sumcols+1;
matchcols=cats(matchcols)!!' '!!cats(name);
end;
%end;
%else %if &match=WILD %then %do;
if _n_=1 then do;
retain wcount;
wcount=countw(cols);
drop wcount;
end;
do i=1 to wcount;
length curword $32;
curword=scan(cols,i,' ');
drop curword;
if index(name,cats(curword)) then do;
sumcols+1;
matchcols=cats(matchcols)!!' '!!cats(curword);
end;
end;
%end;

if last.memname then do;
if sumcols>0 then output;
if sumcols=colcount then putlog "Full Match: " libname memname;
Expand All @@ -5786,10 +5816,11 @@ run;

proc sort; by descending sumcols memname libname; run;

proc sql;
drop table &tempds;
%put &sysmacroname process finished at %sysfunc(datetime(),datetime19.);

%mend;
/**
%mend mp_searchcols;/**
@file
@brief Searches all data in a library
@details
Expand Down
38 changes: 35 additions & 3 deletions base/mp_searchcols.sas
Expand Up @@ -9,14 +9,23 @@
%mp_searchcols(libs=sashelp work, cols=name sex age)
@param libs=
@param libs=(SASHELP) Space separated list of libraries to search for columns
@param cols= Space separated list of column names to search for (not case
sensitive)
@param outds=(mp_searchcols) the table to create with the results. Will have
one line per table match.
@param match=(ANY) The match type. Valid values:
@li ANY - The table contains at least one of the columns
@li WILD - The table contains a column with a name that partially matches
@version 9.2
@author Allan Bowe
**/

%macro mp_searchcols(libs=sashelp
,cols=
,outds=mp_searchcols
,match=ANY
)/*/STORE SOURCE*/;

%put &sysmacroname process began at %sysfunc(datetime(),datetime19.);
Expand All @@ -38,8 +47,10 @@ create table _data_ as
%end;
order by 1,2,3;

%local tempds;
%let tempds=&syslast;
data &outds;
set &syslast;
set &tempds;
length cols matchcols $32767;
cols=upcase(symget('cols'));
colcount=countw(cols);
Expand All @@ -53,10 +64,29 @@ data &outds;
retain matchcols;
matchcols='';
end;
%if &match=ANY %then %do;
if findw(cols,name,,'spit') then do;
sumcols+1;
matchcols=cats(matchcols)!!' '!!cats(name);
end;
%end;
%else %if &match=WILD %then %do;
if _n_=1 then do;
retain wcount;
wcount=countw(cols);
drop wcount;
end;
do i=1 to wcount;
length curword $32;
curword=scan(cols,i,' ');
drop curword;
if index(name,cats(curword)) then do;
sumcols+1;
matchcols=cats(matchcols)!!' '!!cats(curword);
end;
end;
%end;

if last.memname then do;
if sumcols>0 then output;
if sumcols=colcount then putlog "Full Match: " libname memname;
Expand All @@ -66,6 +96,8 @@ run;

proc sort; by descending sumcols memname libname; run;

proc sql;
drop table &tempds;
%put &sysmacroname process finished at %sysfunc(datetime(),datetime19.);

%mend;
%mend mp_searchcols;
50 changes: 50 additions & 0 deletions tests/base/mp_searchcols.test.sas
@@ -0,0 +1,50 @@
/**
@file
@brief Testing mp_searchcols.sas
<h4> SAS Macros </h4>
@li mp_searchcols.sas
@li mp_assertdsobs.sas
**/


/** Test 1 - full col match */
data example1;
var1=1;
var2=2;
var3=3;
data example2;
var1=1;
var2=2;
data example3;
var2=2;
var3=3;
data example4;
matchmehere=1;
data example5;
hereyoucan_matchme_also=1;
data example6;
do_not_forget_me=1;
data example7;
we_shall_not_forget=1;
run;

%mp_searchcols(libs=work,cols=var1 var2,outds=testme)

%mp_assertdsobs(work.testme,
desc=Test1 - check exact variables are found,
test=EQUALS 3,
outds=work.test_results
)

/* test 2 - wildcard match */

%mp_searchcols(libs=work,cols=matchme forget,match=WILD, outds=testme2)

%mp_assertdsobs(work.testme2,
desc=Test1 - check fuzzy matches are found,
test=EQUALS 4,
outds=work.test_results
)

0 comments on commit c6b6536

Please sign in to comment.