/*---------------------------------------------------------------------- © Copyright 2011-2013 University of Manitoba This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ----------------------------------------------------------------------------- Programmer: Say Hong Based on the previous macro by Mahmoud Azimaee Please direct questions and comments to info@cpe.umanitoba.ca Version 2.0 Date: Feb. 21, 2013 This macro perform the following criteria: 1. Check the number and percentage of linkable records of a datasets 2. Generate a distribution table for the phintype Macro Parameter: domain = Libname of the dataset db = dataset prefix or Space separated list of dataset name (or name of the cluster if memnum is non-empty) phin = Name of phin variable (default value is scrphin) type = Name of phintype variable (default value is scrphintype) memnum = ALL or Space separated list of cluster members, if memnum=ALL then this macro will run for all cluster members -----------------------------------------------------------------------*/ %macro dq_link(domain=, db=, phin=scrphin, type=scrphintype, memnum=); %put; %put NOTE: Linkability Macro; %put NOTE: Say Hong; %put NOTE: Based on the previous work by Mahmoud Azimaee; %put; proc datasets nolist memtype=data; delete linkability phintype; quit; %let type=%upcase(&type); proc format; value $phintype '0'='0 MH verified against concurrent registries' '1'='1 MH redirected to this ScrPHIN from FILEPHIN' '2'='2 MCHP modified sibling''s ScrPHIN' '3'='3 MCHP assigned ScrPHIN from Registry' '4'='4 MCHP db specific ScrPHIN - No MH found' '5'='5 MCHP db specific ScrPHIN - personid not incl in crosswalk' '6'='6 Not Defined June 2010' '7'='7 HCN is not Manitoba Resident' '8'='8 Missing or unspecified' '9'='9 System, not individual ScrPHIN' ; run; %if %upcase(&memnum) ^= %then %do; %if %sysfunc(countw(&db)) > 1 %then %do; %put WARNING: Too many cluster datasets have been listed on the parameter db; %put WARNING: If memnum is not empty, this macro can only run for one cluster dataset at a time; %put WARNING: This macro stop without executing; %return; %end; %if %upcase(&memnum) = ALL %then %do; ods output enginehost=clsmem; proc contents data=&domain..&db out=contents; run; ods output close; data _null_; set clsmem; if label1 = 'Cluster Members are' then call symputx('clsmem', cvalue1); run; %* Get cluster members and cluster members name; %let nmem = %sysfunc(countw(%bquote(&clsmem), %str(,))); %let members=; %let memnum=; %do i = 1 %to &nmem; %let temp=%scan(%scan(%bquote(&clsmem), &i, %str(,)), 1, '('); %let members = &members &temp; %let memnum = &memnum &i; %end; proc datasets nolist memtype=data lib=work; delete clsmem; quit; %end; %else %do; %let nmem=%sysfunc(countw(&memnum)); %do i = 1 %to &nmem; proc contents data=&domain..&db(memnum=%scan(&memnum, &i)) out=contents&i noprint; run; %end; data contents; set contents1-contents&nmem; run; ods output enginehost=clsmem; proc contents data=&domain..&db; run; ods output close; data _null_; set clsmem; if label1 = 'Cluster Members are' then call symputx('clsmem', cvalue1); run; %let cnt = 1; %let members =; %let mem = %scan(&memnum, &cnt); %do %while(&mem ne); %let temp=%scan(%scan(%bquote(&clsmem), &mem, %str(,)), 1, '('); %let members = &members &temp; %let cnt = %eval(&cnt+1); %let mem = %scan(&memnum, &cnt); %end; %end; %goto content; %end; %if %upcase(&memnum) = %then %do; %if %sysfunc(countw(&db)) = 1 %then %do; proc sql noprint; select memname into :dsn_lst separated by ' ' from dictionary.members where libname = "%upcase(&domain)" and substr(memname, 1, %length(&db))="%upcase(&db)"; quit; %end; %else %let dsn_lst = &db; %let n_dsn = %sysfunc(countw(&dsn_lst)); %do i = 1 %to &n_dsn; proc contents data=&domain..%scan(&dsn_lst, &i) out=contents&i noprint; run; %end; data contents; set contents1-contents&n_dsn; run; proc datasets nolist memtype=data lib=work; delete contents1-contents%sysfunc(compress(&n_dsn)); quit; %goto content; %end; %content: data contents; set contents(keep=libname memname memlabel name nobs); if upcase(name)="%upcase(&phin)"; run; data _null_; if 0 then set contents nobs=n; call symputx('nobs', n); stop; run; %if &nobs = 0 %then %do; %put WARNING: None of the selected tables had &phin variables; %put WARNING: Macro stop without generating any output; %return; %end; %if %upcase(&memnum) ^= %then %do; %do i = 1 %to &nmem; %let mem = %scan(&memnum, &i); proc freq data=&domain..&db(memnum=&mem keep=&type) noprint; tables &type/missing out=phintype&i(drop=count /*rename=(percent=%scan(&members, &i))*/); run; data phintype&i; drop percent; set phintype&i; %scan(&members, &i) = input(put(percent, 5.2),8.); run; data _null_; if 0 then set &domain..&db(memnum=&mem) nobs=nobs; call symputx("nobs&i", nobs); stop; run; proc sql noprint; select count(*), count (distinct &phin) into :no_rec&i, :pt_rec&i from &domain..&db(memnum=&mem keep=&phin &type) where &type in ('0','1','2','3','6'); quit; %end; data linkability; length Table $32; %do i = 1 %to &nmem; Table = "%scan(&members, &i)"; Total_record = &&nobs&i; Linkable_record = &&no_rec&i; Percent_linkable_record = input(put(100*Linkable_record/Total_record, 5.2), 8.); Linkable_individuals = &&pt_rec&i; output; %end; label Table = 'Dataset' Total_record = 'Total Number of Records' Linkable_record = 'Number of Linkable Records' Percent_linkable_record = '% Linkable Records' Linkable_individuals = 'Number of Linkable Individuals'; run; data phintype; length &type $60; merge phintype1-phintype%sysfunc(compress(&nmem)); by &type; &type = put(&type, $phintype.); run; proc datasets nolist memtype=data lib=work; delete phintype1-phintype%sysfunc(compress(&nmem)); quit; %end; %if %upcase(&memnum) = %then %do; proc sql noprint; select memname, count(*) into :dsn_lst separated by ' ', :n_dsn from contents; quit; %do i = 1 %to &n_dsn; proc freq data=&domain..%scan(&dsn_lst, &i)(keep=&type) noprint; tables &type/missing out=phintype&i(drop=count /*rename=(percent=%scan(&dsn_lst, &i))*/); run; data phintype&i; drop percent; set phintype&i; %scan(&dsn_lst, &i) = input(put(percent, 5.2), 8.); run; data _null_; if 0 then set &domain..%scan(&dsn_lst, &i) nobs=nobs; call symputx("nobs&i", nobs); stop; run; proc sql noprint; select count(*), count (distinct &phin) into :no_rec&i, :pt_rec&i from &domain..%scan(&dsn_lst, &i)(keep=&phin &type) where &type in ('0','1','2','3','6'); quit; %end; data linkability; length Table $32; %do i = 1 %to &n_dsn; Table = "%scan(&dsn_lst, &i)"; Total_record = &&nobs&i; Linkable_record = &&no_rec&i; Percent_linkable_record = input(put(100*Linkable_record/Total_record, 5.2), 8.); Linkable_individuals = &&pt_rec&i; output; %end; label Table = 'Dataset' Total_record = 'Total Number of Records' Linkable_record = 'Number of Linkable Records' Percent_linkable_record = '% Linkable Records' Linkable_individuals = 'Number of Linkable Individuals'; run; data phintype; length &type $60; merge phintype1-phintype%sysfunc(compress(&n_dsn)); by &type; &type = put(&type, $phintype.); run; proc datasets nolist memtype=data lib=work; delete phintype1-phintype%sysfunc(compress(&n_dsn)); quit; %end; proc print data=phintype; run; proc print data=linkability; run; proc datasets nolist memtype=data lib=work; delete contents; quit; %if %substr(&dq_dir, %length(&dq_dir), 1) = \ %then %let dq_dir = %substr(&dq_dir, 1, %length(&dq_dir) - 1); %if %substr(&sysscpl, 1, 3) = X64 or %substr(&sysscpl, 1, 3) = W64 %then %let dbms = excelcs; %else %let dbms = excel; proc export data=phintype outfile="&dq_dir\&dq_name..xls" dbms=&dbms replace; sheet = 'phintype'; run; proc export data=linkability outfile="&dq_dir\&dq_name..xls" dbms=&dbms label replace; sheet = 'linkability'; run; %mend dq_link;