Thursday, 11 September 2025

286.REAL WORLD BLOOD BANKS ANALYSIS USING PROC PRINT|PROC FORMAT|PROC FREQ|PROC MEANS|PROC SQL|PROC SORT|PROC REPORT|PROC TRANSPOSE WITH MACROS AND QC CHECKS FOR UTILIZATION,LOW INVENTORY ALERTS, TYPE-WISE REPORTS AND COUNTRY LEVEL AGGREGATION

REAL WORLD BLOOD BANKS ANALYSIS USING PROC PRINT|PROC FORMAT|PROC FREQ|PROC MEANS|PROC SQL|PROC SORT|PROC REPORT|PROC TRANSPOSE WITH MACROS AND QC CHECKS FOR UTILIZATION,LOW INVENTORY ALERTS, TYPE-WISE REPORTS AND COUNTRY LEVEL AGGREGATION

/*Creating The dataset of REAL_BLOODBANKS */

options  nocenter;

data work.real_bloodbanks;

  informat LastInspection date9.;

  format LastInspection date9. CapacityUnits comma8. CurrentInventory comma8.;

  input BankID $ BankName :$40. Country :$30. City :$30. Type :$10.

        CapacityUnits CurrentInventory Contact :$15. LastInspection :date9.;

  datalines;

BB001 InternationalBloodCenter USA New_York NGO 50000 23500 +1-212-555-0101 15JAN2025

BB002 RoyalBloodBank UK London Public 60000 41200 +44-20-7946-0001 02FEB2025

BB003 LifelineMedical India Hyderabad Private 30000 11800 +91-40-1234-5678 10MAR2025

BB004 RedCrossCentral Australia Sydney NGO 45000 21000 +61-2-9999-1000 05APR2025

BB005 EuroBloodServices Germany Berlin Public 52000 30100 +49-30-123-4567 20JAN2025

BB006 PacificCare Japan Tokyo Private 40000 19500 +81-3-9876-5432 28FEB2025

BB007 VitalDonorSouth Africa Johannesburg NGO 20000 7200 +27-11-555-1234 12MAR2025

BB008 AndesHealth Chile Santiago Public 18000 8200 +56-2-2345-6789 18FEB2025

BB009 AmazonLife Brazil Manaus NGO 15000 5200 +55-92-9987-6543 22JAN2025

BB010 NorthStarCanada Canada Toronto Private 35000 17800 +1-416-555-0199 30MAR2025

BB011 MedServeFrance France Paris Public 48000 40250 +33-1-2345-6789 08APR2025

BB012 DesertCare UAE Dubai Private 22000 9200 +971-4-555-6789 25FEB2025

;

run;

proc print;run;

Output:

ObsLastInspectionCapacityUnitsCurrentInventoryBankIDBankNameCountryCityTypeContact
115JAN202550,00023,500BB001InternationalBloodCenterUSANew_YorkNGO+1-212-555-0101
202FEB202560,00041,200BB002RoyalBloodBankUKLondonPublic+44-20-7946-000
310MAR202530,00011,800BB003LifelineMedicalIndiaHyderabadPrivate+91-40-1234-567
405APR202545,00021,000BB004RedCrossCentralAustraliaSydneyNGO+61-2-9999-1000
520JAN202552,00030,100BB005EuroBloodServicesGermanyBerlinPublic+49-30-123-4567
628FEB202540,00019,500BB006PacificCareJapanTokyoPrivate+81-3-9876-5432
712MAR202520,0007,200BB007VitalDonorSouthAfricaJohannesburgNGO+27-11-555-1234
818FEB202518,0008,200BB008AndesHealthChileSantiagoPublic+56-2-2345-6789
922JAN202515,0005,200BB009AmazonLifeBrazilManausNGO+55-92-9987-654
1030MAR202535,00017,800BB010NorthStarCanadaCanadaTorontoPrivate+1-416-555-0199
1108APR202548,00040,250BB011MedServeFranceFranceParisPublic+33-1-2345-6789
1225FEB202522,0009,200BB012DesertCareUAEDubaiPrivate+971-4-555-6789


 1) PROC PRINT -  show data rows for inspection 

proc print data=work.real_bloodbanks(obs=10) label noobs;

  title "REAL_BLOODBANKS - SAMPLE INSPECTION";

  var BankID BankName Country City Type CapacityUnits CurrentInventory LastInspection Contact;

run;

Output:

REAL_BLOODBANKS - SAMPLE INSPECTION

BankIDBankNameCountryCityTypeCapacityUnitsCurrentInventoryLastInspectionContact
BB001InternationalBloodCenterUSANew_YorkNGO50,00023,50015JAN2025+1-212-555-0101
BB002RoyalBloodBankUKLondonPublic60,00041,20002FEB2025+44-20-7946-000
BB003LifelineMedicalIndiaHyderabadPrivate30,00011,80010MAR2025+91-40-1234-567
BB004RedCrossCentralAustraliaSydneyNGO45,00021,00005APR2025+61-2-9999-1000
BB005EuroBloodServicesGermanyBerlinPublic52,00030,10020JAN2025+49-30-123-4567
BB006PacificCareJapanTokyoPrivate40,00019,50028FEB2025+81-3-9876-5432
BB007VitalDonorSouthAfricaJohannesburgNGO20,0007,20012MAR2025+27-11-555-1234
BB008AndesHealthChileSantiagoPublic18,0008,20018FEB2025+56-2-2345-6789
BB009AmazonLifeBrazilManausNGO15,0005,20022JAN2025+55-92-9987-654
BB010NorthStarCanadaCanadaTorontoPrivate35,00017,80030MAR2025+1-416-555-0199

 2) PROC FORMAT - map Type values to friendly labels 

proc format;

  value $ttype

    'Public' = 'PUBLIC'

    'Private' = 'PRIVATE'

    'NGO' = 'NGO/NOT-FOR-PROFIT';

run;

Log:

NOTE: Format $TTYPE has been output.

 3) PROC FREQ -  frequency of bank types and countries 

proc freq data=work.real_bloodbanks;

  tables Type Country / nocum nopercent;

  format Type $ttype.;

  title "FREQUENCY: TYPE & COUNTRY";

run;

Output:

FREQUENCY: TYPE & COUNTRY

The FREQ Procedure

TypeFrequency
NGO/NOT-FOR-PROFIT4
PRIVATE4
PUBLIC4
CountryFrequency
Africa1
Australia1
Brazil1
Canada1
Chile1
France1
Germany1
India1
Japan1
UAE1
UK1
USA1

 4) PROC MEANS -  numeric summary of capacities/inventory 

proc means data=work.real_bloodbanks n mean median min max std maxdec=0;

  var CapacityUnits CurrentInventory;

  title "SUMMARY STATISTICS: Capacity and CurrentInventory";

run;

Output:

SUMMARY STATISTICS: Capacity and CurrentInventory

The MEANS Procedure

VariableNMeanMedianMinimumMaximumStd Dev
CapacityUnits
CurrentInventory
12
12
36250
19579
37500
18650
15000
5200
60000
41200
15143
12372

 5) PROC SQL - compute inventory utilization and create summary table 

proc sql;

  create table work.bb_utilization as

  select BankID,BankName,Country,City,Type,

         CapacityUnits,

         CurrentInventory,

         (CurrentInventory / CapacityUnits) as Utilization format=percent8.2

  from work.real_bloodbanks

  order by Utilization desc;

quit;

proc print;run;

Output:

ObsBankIDBankNameCountryCityTypeCapacityUnitsCurrentInventoryUtilization
1BB011MedServeFranceFranceParisPublic48,00040,25083.85%
2BB002RoyalBloodBankUKLondonPublic60,00041,20068.67%
3BB005EuroBloodServicesGermanyBerlinPublic52,00030,10057.88%
4BB010NorthStarCanadaCanadaTorontoPrivate35,00017,80050.86%
5BB006PacificCareJapanTokyoPrivate40,00019,50048.75%
6BB001InternationalBloodCenterUSANew_YorkNGO50,00023,50047.00%
7BB004RedCrossCentralAustraliaSydneyNGO45,00021,00046.67%
8BB008AndesHealthChileSantiagoPublic18,0008,20045.56%
9BB012DesertCareUAEDubaiPrivate22,0009,20041.82%
10BB003LifelineMedicalIndiaHyderabadPrivate30,00011,80039.33%
11BB007VitalDonorSouthAfricaJohannesburgNGO20,0007,20036.00%
12BB009AmazonLifeBrazilManausNGO15,0005,20034.67%


6) PROC SORT - sort by utilization for reporting 

proc sort data=work.bb_utilization out=work.bb_utilization_srt;

  by descending Utilization BankName;

run;

proc print;run;

Output:

ObsBankIDBankNameCountryCityTypeCapacityUnitsCurrentInventoryUtilization
1BB011MedServeFranceFranceParisPublic48,00040,25083.85%
2BB002RoyalBloodBankUKLondonPublic60,00041,20068.67%
3BB005EuroBloodServicesGermanyBerlinPublic52,00030,10057.88%
4BB010NorthStarCanadaCanadaTorontoPrivate35,00017,80050.86%
5BB006PacificCareJapanTokyoPrivate40,00019,50048.75%
6BB001InternationalBloodCenterUSANew_YorkNGO50,00023,50047.00%
7BB004RedCrossCentralAustraliaSydneyNGO45,00021,00046.67%
8BB008AndesHealthChileSantiagoPublic18,0008,20045.56%
9BB012DesertCareUAEDubaiPrivate22,0009,20041.82%
10BB003LifelineMedicalIndiaHyderabadPrivate30,00011,80039.33%
11BB007VitalDonorSouthAfricaJohannesburgNGO20,0007,20036.00%
12BB009AmazonLifeBrazilManausNGO15,0005,20034.67%


7) PROC REPORT - formatted report with computed column for alert 

proc report data=work.bb_utilization_srt nowd headline;

  column BankID BankName Country City Type CapacityUnits CurrentInventory Utilization 

         Alert;

  define BankID / group 'ID';

  define BankName / display 'Center Name';

  define Country / display 'Country';

  define City / display 'City';

  define Type / display 'Type' format=$ttype.;

  define CapacityUnits / analysis sum 'Capacity (U)';

  define CurrentInventory / analysis sum 'Inventory (U)';

  define Utilization / display 'Utilization';

  compute Utilization;

    Utilization = Utilization;

  endcomp;

  compute Alert / character length=12;

    if Utilization < 0.25 then Alert='LOW-STOCK';

    else if Utilization < 0.5 then Alert='WATCH';

    else Alert='OK';

  endcomp;

  title "BLOOD BANK UTILIZATION REPORT WITH ALERTS";

run;

Output:

BLOOD BANK UTILIZATION REPORT WITH ALERTS

IDCenter NameCountryCityTypeCapacity (U)Inventory (U)UtilizationAlert
BB001InternationalBloodCenterUSANew_YorkNGO/NOT-FOR-PROFIT50,00023,50047.00%WATCH
BB002RoyalBloodBankUKLondonPUBLIC60,00041,20068.67%OK
BB003LifelineMedicalIndiaHyderabadPRIVATE30,00011,80039.33%WATCH
BB004RedCrossCentralAustraliaSydneyNGO/NOT-FOR-PROFIT45,00021,00046.67%WATCH
BB005EuroBloodServicesGermanyBerlinPUBLIC52,00030,10057.88%OK
BB006PacificCareJapanTokyoPRIVATE40,00019,50048.75%WATCH
BB007VitalDonorSouthAfricaJohannesburgNGO/NOT-FOR-PROFIT20,0007,20036.00%WATCH
BB008AndesHealthChileSantiagoPUBLIC18,0008,20045.56%WATCH
BB009AmazonLifeBrazilManausNGO/NOT-FOR-PROFIT15,0005,20034.67%WATCH
BB010NorthStarCanadaCanadaTorontoPRIVATE35,00017,80050.86%OK
BB011MedServeFranceFranceParisPUBLIC48,00040,25083.85%OK
BB012DesertCareUAEDubaiPRIVATE22,0009,20041.82%WATCH

 8) PROC TRANSPOSE - create wide view (country-level inventory) 

proc sql;

  create table work.country_inventory as

  select Country,

         sum(CapacityUnits) as TotalCapacity,

         sum(CurrentInventory) as TotalInventory,

         calculated TotalInventory / calculated TotalCapacity as CountryUtilization

  from work.real_bloodbanks

  group by Country;

quit;

proc print;run;

Output:

ObsCountryTotalCapacityTotalInventoryCountryUtilization
1Africa2000072000.36000
2Australia45000210000.46667
3Brazil1500052000.34667
4Canada35000178000.50857
5Chile1800082000.45556
6France48000402500.83854
7Germany52000301000.57885
8India30000118000.39333
9Japan40000195000.48750
10UAE2200092000.41818
11UK60000412000.68667
12USA50000235000.47000


proc transpose data=work.country_inventory out=work.country_inventory_t(drop=_NAME_);

  id Country;

  var TotalCapacity TotalInventory CountryUtilization;

run;

proc print;run;

Output:

ObsAfricaAustraliaBrazilCanadaChileFranceGermanyIndiaJapanUAEUKUSA
120000.0045000.0015000.0035000.0018000.0048000.0052000.0030000.0040000.0022000.0060000.0050000.00
27200.0021000.005200.0017800.008200.0040250.0030100.0011800.0019500.009200.0041200.0023500.00
30.360.470.350.510.460.840.580.390.490.420.690.47

 

9) Macro: %low_inventory_alert - make a dataset of banks below a threshold 

%macro low_inventory_alert(thresh=0.25, outds=work.low_alerts);

/*   Creates &outds with banks with utilization < &thresh */

  proc sql;

    create table &outds as

    select BankID, BankName, Country, City, Type, CapacityUnits, CurrentInventory,

           CurrentInventory / CapacityUnits as Utilization format=percent8.2

    from work.real_bloodbanks

    where (CurrentInventory / CapacityUnits) < &thresh

    order by Utilization;

  quit;

  proc print data=&outds;run;

%mend low_inventory_alert;


%low_inventory_alert(thresh=0.25, outds=work.low_alerts);

Log:

NOTE: Table WORK.LOW_ALERTS created, with 0 rows and 8 columns.

 10) Macro: %bb_report_by_type - generate type-wise PDF/CENTRIC report (simulated) 

%macro bb_report_by_type(bbtype=Public);

  %let bbtype_clean = %sysfunc(strip(&bbtype));

  proc sql noprint;

    create table work._tmp as

    select * from work.real_bloodbanks

    where Type = "&bbtype_clean";

  quit;


  proc print data=work._tmp noobs;

    title "Report for Type=&bbtype_clean";

  run;


  proc sql;

    drop table work._tmp;

  quit;

%mend bb_report_by_type;


%bb_report_by_type(bbtype=NGO);

Output:

Report for Type=NGO

LastInspectionCapacityUnitsCurrentInventoryBankIDBankNameCountryCityTypeContact
15JAN202550,00023,500BB001InternationalBloodCenterUSANew_YorkNGO+1-212-555-0101
05APR202545,00021,000BB004RedCrossCentralAustraliaSydneyNGO+61-2-9999-1000
12MAR202520,0007,200BB007VitalDonorSouthAfricaJohannesburgNGO+27-11-555-1234
22JAN202515,0005,200BB009AmazonLifeBrazilManausNGO+55-92-9987-654

 11) Simple validation/QC - check for missing or invalid values 

proc sql;

  create table work.qc_checks as

  select BankID,

         case when BankName is null then 'MISSING_NAME' else '' end as NameFlag,

         case when CapacityUnits <= 0 then 'INVALID_CAPACITY' else '' end as CapacityFlag,

         case when CurrentInventory < 0 then 'NEG_INV' else '' end as InventoryFlag,

         case when LastInspection is missing then 'NO_INSPECTION_DATE' else '' end as InspectionFlag

  from work.real_bloodbanks;

quit;

proc print;run;

Output:

ObsBankIDNameFlagCapacityFlagInventoryFlagInspectionFlag
1BB001    
2BB002    
3BB003    
4BB004    
5BB005    
6BB006    
7BB007    
8BB008    
9BB009    
10BB010    
11BB011    
12BB012    


 12)left join with a mock 'donor_drive' table using PROC SQL - demonstrate joins 

data work.donor_drive;

  input BankID $ DriveDate :date9. UnitsCollected;

  format DriveDate date9. UnitsCollected comma6.;

datalines;

BB001 05MAR2025 1200

BB003 15MAR2025 800

BB006 10FEB2025 900

BB009 01JAN2025 450

BB012 12FEB2025 300

;

run;

proc print;run;

Output:

ObsBankIDDriveDateUnitsCollected
1BB00105MAR20251,200
2BB00315MAR2025800
3BB00610FEB2025900
4BB00901JAN2025450
5BB01212FEB2025300


proc sql;

  create table work.bb_with_drives as

  select a.*, b.DriveDate, b.UnitsCollected

  from work.real_bloodbanks as a

  left join work.donor_drive as b

  on a.BankID = b.BankID;

quit;

proc prinr;run;

Output:

ObsLastInspectionCapacityUnitsCurrentInventoryBankIDBankNameCountryCityTypeContactDriveDateUnitsCollected
115JAN202550,00023,500BB001InternationalBloodCenterUSANew_YorkNGO+1-212-555-010105MAR20251,200
202FEB202560,00041,200BB002RoyalBloodBankUKLondonPublic+44-20-7946-000..
310MAR202530,00011,800BB003LifelineMedicalIndiaHyderabadPrivate+91-40-1234-56715MAR2025800
405APR202545,00021,000BB004RedCrossCentralAustraliaSydneyNGO+61-2-9999-1000..
520JAN202552,00030,100BB005EuroBloodServicesGermanyBerlinPublic+49-30-123-4567..
628FEB202540,00019,500BB006PacificCareJapanTokyoPrivate+81-3-9876-543210FEB2025900
712MAR202520,0007,200BB007VitalDonorSouthAfricaJohannesburgNGO+27-11-555-1234..
818FEB202518,0008,200BB008AndesHealthChileSantiagoPublic+56-2-2345-6789..
922JAN202515,0005,200BB009AmazonLifeBrazilManausNGO+55-92-9987-65401JAN2025450
1030MAR202535,00017,800BB010NorthStarCanadaCanadaTorontoPrivate+1-416-555-0199..
1108APR202548,00040,250BB011MedServeFranceFranceParisPublic+33-1-2345-6789..
1225FEB202522,0009,200BB012DesertCareUAEDubaiPrivate+971-4-555-678912FEB2025300






To Visit My Previous Online Streaming Flatform Dataset:Click Here
To Visit My Previous Statistical Evaluation Of Clinical Trials:Click Here
To Visit My Previous Unlocking Retail Insights Dataset:Click Here
To Visit My Previous Sas Interview Questions-1:Click Here  



Follow Us On : 


 


--- FOLLOW OUR BLOG FOR MORE INFORMATION.

--->PLEASE DO COMMENTS AND SHARE OUR BLOG.

No comments:

Post a Comment