mirror of
https://github.com/sasjs/core.git
synced 2026-01-05 00:20:05 +00:00
feat: adding MATCH parameter to mp_searchcols.sas to enable fuzzy matching on columns. Closes #14
This commit is contained in:
41
all.sas
41
all.sas
@@ -2945,7 +2945,7 @@ run;
|
|||||||
proc sql;
|
proc sql;
|
||||||
create table data1 as select * from sashelp.class;
|
create table data1 as select * from sashelp.class;
|
||||||
create view view2 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>
|
<h4> SAS Macros </h4>
|
||||||
@@ -5729,7 +5729,15 @@ run;
|
|||||||
|
|
||||||
%mp_searchcols(libs=sashelp work, cols=name sex age)
|
%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
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
**/
|
**/
|
||||||
@@ -5737,6 +5745,7 @@ run;
|
|||||||
%macro mp_searchcols(libs=sashelp
|
%macro mp_searchcols(libs=sashelp
|
||||||
,cols=
|
,cols=
|
||||||
,outds=mp_searchcols
|
,outds=mp_searchcols
|
||||||
|
,match=ANY
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%put &sysmacroname process began at %sysfunc(datetime(),datetime19.);
|
%put &sysmacroname process began at %sysfunc(datetime(),datetime19.);
|
||||||
@@ -5758,8 +5767,10 @@ create table _data_ as
|
|||||||
%end;
|
%end;
|
||||||
order by 1,2,3;
|
order by 1,2,3;
|
||||||
|
|
||||||
|
%local tempds;
|
||||||
|
%let tempds=&syslast;
|
||||||
data &outds;
|
data &outds;
|
||||||
set &syslast;
|
set &tempds;
|
||||||
length cols matchcols $32767;
|
length cols matchcols $32767;
|
||||||
cols=upcase(symget('cols'));
|
cols=upcase(symget('cols'));
|
||||||
colcount=countw(cols);
|
colcount=countw(cols);
|
||||||
@@ -5773,10 +5784,29 @@ data &outds;
|
|||||||
retain matchcols;
|
retain matchcols;
|
||||||
matchcols='';
|
matchcols='';
|
||||||
end;
|
end;
|
||||||
|
%if &match=ANY %then %do;
|
||||||
if findw(cols,name,,'spit') then do;
|
if findw(cols,name,,'spit') then do;
|
||||||
sumcols+1;
|
sumcols+1;
|
||||||
matchcols=cats(matchcols)!!' '!!cats(name);
|
matchcols=cats(matchcols)!!' '!!cats(name);
|
||||||
end;
|
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 last.memname then do;
|
||||||
if sumcols>0 then output;
|
if sumcols>0 then output;
|
||||||
if sumcols=colcount then putlog "Full Match: " libname memname;
|
if sumcols=colcount then putlog "Full Match: " libname memname;
|
||||||
@@ -5786,10 +5816,11 @@ run;
|
|||||||
|
|
||||||
proc sort; by descending sumcols memname libname; run;
|
proc sort; by descending sumcols memname libname; run;
|
||||||
|
|
||||||
|
proc sql;
|
||||||
|
drop table &tempds;
|
||||||
%put &sysmacroname process finished at %sysfunc(datetime(),datetime19.);
|
%put &sysmacroname process finished at %sysfunc(datetime(),datetime19.);
|
||||||
|
|
||||||
%mend;
|
%mend mp_searchcols;/**
|
||||||
/**
|
|
||||||
@file
|
@file
|
||||||
@brief Searches all data in a library
|
@brief Searches all data in a library
|
||||||
@details
|
@details
|
||||||
|
|||||||
@@ -9,7 +9,15 @@
|
|||||||
|
|
||||||
%mp_searchcols(libs=sashelp work, cols=name sex age)
|
%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
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
**/
|
**/
|
||||||
@@ -17,6 +25,7 @@
|
|||||||
%macro mp_searchcols(libs=sashelp
|
%macro mp_searchcols(libs=sashelp
|
||||||
,cols=
|
,cols=
|
||||||
,outds=mp_searchcols
|
,outds=mp_searchcols
|
||||||
|
,match=ANY
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%put &sysmacroname process began at %sysfunc(datetime(),datetime19.);
|
%put &sysmacroname process began at %sysfunc(datetime(),datetime19.);
|
||||||
@@ -38,8 +47,10 @@ create table _data_ as
|
|||||||
%end;
|
%end;
|
||||||
order by 1,2,3;
|
order by 1,2,3;
|
||||||
|
|
||||||
|
%local tempds;
|
||||||
|
%let tempds=&syslast;
|
||||||
data &outds;
|
data &outds;
|
||||||
set &syslast;
|
set &tempds;
|
||||||
length cols matchcols $32767;
|
length cols matchcols $32767;
|
||||||
cols=upcase(symget('cols'));
|
cols=upcase(symget('cols'));
|
||||||
colcount=countw(cols);
|
colcount=countw(cols);
|
||||||
@@ -53,10 +64,29 @@ data &outds;
|
|||||||
retain matchcols;
|
retain matchcols;
|
||||||
matchcols='';
|
matchcols='';
|
||||||
end;
|
end;
|
||||||
|
%if &match=ANY %then %do;
|
||||||
if findw(cols,name,,'spit') then do;
|
if findw(cols,name,,'spit') then do;
|
||||||
sumcols+1;
|
sumcols+1;
|
||||||
matchcols=cats(matchcols)!!' '!!cats(name);
|
matchcols=cats(matchcols)!!' '!!cats(name);
|
||||||
end;
|
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 last.memname then do;
|
||||||
if sumcols>0 then output;
|
if sumcols>0 then output;
|
||||||
if sumcols=colcount then putlog "Full Match: " libname memname;
|
if sumcols=colcount then putlog "Full Match: " libname memname;
|
||||||
@@ -66,6 +96,8 @@ run;
|
|||||||
|
|
||||||
proc sort; by descending sumcols memname libname; run;
|
proc sort; by descending sumcols memname libname; run;
|
||||||
|
|
||||||
|
proc sql;
|
||||||
|
drop table &tempds;
|
||||||
%put &sysmacroname process finished at %sysfunc(datetime(),datetime19.);
|
%put &sysmacroname process finished at %sysfunc(datetime(),datetime19.);
|
||||||
|
|
||||||
%mend;
|
%mend mp_searchcols;
|
||||||
50
tests/base/mp_searchcols.test.sas
Normal file
50
tests/base/mp_searchcols.test.sas
Normal file
@@ -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
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user