718.Can We Design, Debug, Detect Fraud, And Optimize A Smart Parking System Using Advanced SAS Programming Techniques?
Smart Parking Analytics Engine: From Data Errors To Revenue Control
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
HERE IN THIS PROJECT WE USED THESE SAS STATEMENTS —DATA STEP | SET | IF-THEN-ELSE | PROC PRINT | PROC SQL | SELECT | SUM | COUNT | GROUP BY | LEFT JOIN | PROC SORT | MERGE | PROC APPEND | PROC TRANSPOSE | PROC DATASETS DELETE | MACRO | RUN | QUIT
In
today’s urban environments, smart parking systems play a critical role in
reducing traffic congestion, fuel consumption, and driver frustration. Cities
are investing in IoT-enabled parking sensors, real-time occupancy dashboards,
automated billing, and predictive analytics to manage parking spaces
efficiently.
·
Data creation and simulation
·
Fraud detection logic
·
Data validation and debugging
·
Macro automation
·
Performance analytics
·
Error correction and QC
In this
project, we will:
·
Create a dataset with more than 15 observations
·
Intentionally introduce data errors
·
Debug and correct those errors
·
Apply DATA step, PROC SQL, and MACROS
·
Use date functions (MDY, INTCK, INTNX)
·
Use SET, MERGE, APPEND, TRANSPOSE
·
Apply numeric and character functions
·
Use PROC DATASETS DELETE
·
Build fraud detection logic
This
project is not just about dataset creation. It simulates a real-world Smart
City Analytics Platform using SAS programming concepts including:
·
DATA step processing
·
PROC SQL
·
Macros
·
Date functions (MDY, INTCK, INTNX)
·
Character functions (STRIP, TRIM, PROPCASE, UPCASE, LOWCASE, CAT, CATX)
·
Numeric functions (ROUND, ABS, COALESCE)
·
SET, MERGE, APPEND, TRANSPOSE
·
PROC DATASETS DELETE
·
Fraud scoring models
Table Of Contents
1.
Raw Dataset With Intentional Errors
2.
Corrected Full Dataset Code
3.
Fraud Detection Macro
4.
Append Operation (PROC APPEND)
5.
Merge Operation (DATA Step MERGE)
6.
Transpose Operation (PROC TRANSPOSE)
7.
Dataset Deletion (PROC DATASETS DELETE)
8.
Revenue Analysis Using PROC SQL
9.
Sensor-Level Dataset Creation
10. Payment
Transaction Dataset Creation
11. Revenue
Reconciliation Logic (SQL Join)
12. Revenue
Leak Fraud Indicator
13. Advanced
Fraud Scoring Model
14. Efficiency
KPI Framework
15. Real-Time
Utilization Engine
16. Predictive
Maintenance Engine
17. Data
Quality Validation Macro
18. Audit
Trail System
19. Performance
Optimization Using Indexing
20. 20
Key Points
21. Summary
22. Conclusion
BUSINESS CONTEXT
Imagine a metropolitan smart city like:
·
Hyderabad
·
Mumbai
·
Delhi
·
Bengaluru
·
Chennai
·
Pune
Each city operates hundreds of smart parking
lots equipped with:
·
IoT sensors per slot
·
Digital payment systems
·
Mobile booking apps
·
Automated revenue collection
·
Maintenance scheduling systems
However, real-world challenges exist:
1.
Occupancy manipulation
2.
Revenue leakage
3.
Cash skimming
4.
Sensor malfunction
5.
Ghost billing
6.
System downtime
7.
Payment mismatch
8.
Data inconsistency
9.
Fraudulent manual overrides
10. Poor
maintenance tracking
Municipal corporations require:
·
Accurate utilization metrics
·
Transparent revenue reporting
·
Fraud monitoring system
·
Operational efficiency KPIs
·
Predictive analytics
· Automated validation
1. RAW DATASET WITH INTENTIONAL ERRORS
data smart_parking_raw;
length Parking_ID $5 City $20 Util_Class $15;
format Install_Date Last_Maint_Date date9.;
input Parking_ID $ City $ Slots_Total Occupancy_Rate Avg_Search_Time Revenue
Efficiency_Score Install_Date :date9. Last_Maint_Date :date9.;
datalines;
P001 Hyderabad 100 85 5 15000 92 01JAN2024 01MAR2024
P002 mumbai 200 110 4 30000 105 15FEB2024 01APR2024
P003 DELHI 150 75 6 -2000 88 01MAR2024 10MAR2024
P004 Bengaluru 120 . 7 18000 90 05JAN2024 01FEB2024
P005 Chennai 80 95 3 12000 95 01APR2024 01APR2024
P006 Pune 60 45 8 8000 70 01JAN2024 15JAN2024
P007 Hyderabad 90 100 2 20000 99 01JAN2024 01FEB2024
P008 Mumbai 110 60 9 17000 85 01MAR2024 01MAR2024
P009 Delhi 140 70 10 21000 87 01JAN2024 01APR2024
P010 Bengaluru 130 85 6 22000 93 01FEB2024 01MAR2024
P011 Chennai 95 50 12 5000 60 01JAN2024 01JAN2024
P012 Pune 75 40 15 4000 55 01JAN2024 10JAN2024
P013 Hyderabad 200 180 3 50000 98 01JAN2024 01APR2024
P014 Mumbai 100 0 20 0 20 01JAN2024 01JAN2024
P015 Delhi 160 150 4 45000 96 01JAN2024 01MAR2024
;
run;
proc print data=smart_parking_raw;
run;
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P001 | Hyderabad | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | |
| 2 | P002 | mumbai | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 105 | |
| 3 | P003 | DELHI | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | -2000 | 88 | |
| 4 | P004 | Bengaluru | 05JAN2024 | 01FEB2024 | 120 | . | 7 | 18000 | 90 | |
| 5 | P005 | Chennai | 01APR2024 | 01APR2024 | 80 | 95 | 3 | 12000 | 95 | |
| 6 | P006 | Pune | 01JAN2024 | 15JAN2024 | 60 | 45 | 8 | 8000 | 70 | |
| 7 | P007 | Hyderabad | 01JAN2024 | 01FEB2024 | 90 | 100 | 2 | 20000 | 99 | |
| 8 | P008 | Mumbai | 01MAR2024 | 01MAR2024 | 110 | 60 | 9 | 17000 | 85 | |
| 9 | P009 | Delhi | 01JAN2024 | 01APR2024 | 140 | 70 | 10 | 21000 | 87 | |
| 10 | P010 | Bengaluru | 01FEB2024 | 01MAR2024 | 130 | 85 | 6 | 22000 | 93 | |
| 11 | P011 | Chennai | 01JAN2024 | 01JAN2024 | 95 | 50 | 12 | 5000 | 60 | |
| 12 | P012 | Pune | 01JAN2024 | 10JAN2024 | 75 | 40 | 15 | 4000 | 55 | |
| 13 | P013 | Hyderabad | 01JAN2024 | 01APR2024 | 200 | 180 | 3 | 50000 | 98 | |
| 14 | P014 | Mumbai | 01JAN2024 | 01JAN2024 | 100 | 0 | 20 | 0 | 20 | |
| 15 | P015 | Delhi | 01JAN2024 | 01MAR2024 | 160 | 150 | 4 | 45000 | 96 |
❌
Intentional Errors Introduced
|
Error |
Explanation |
|
Occupancy > Slots |
P002, P005 |
|
Efficiency > 100 |
P002 |
|
Negative Revenue |
P003 |
|
Missing Occupancy |
P004 |
|
100% Occupancy unrealistic |
P007 |
|
Zero revenue but slots exist |
P014 |
|
Mixed case city names |
mumbai, DELHI |
|
Same Install & Maintenance date |
Several records |
2. CORRECTED FULL DATASET CODE
data smart_parking_clean;
set smart_parking_raw;
City = propcase(strip(City));
Occupied_Slots = round((Occupancy_Rate/100) * Slots_Total);
if Occupied_Slots > Slots_Total then Occupied_Slots = Slots_Total;
if Revenue < 0 then Revenue = 0;
if Efficiency_Score > 100 then Efficiency_Score = 100;
if missing(Occupancy_Rate) then Occupancy_Rate = 0;
Utilization_Percent = round((Occupied_Slots/Slots_Total)*100,0.1);
if Utilization_Percent >= 85 then Util_Class="High";
else if Utilization_Percent >=60 then Util_Class="Medium";
else Util_Class="Low";
Parking_Name = catx("_",upcase(City),Parking_ID);
Months_Operational = intck('month',Install_Date,today());
Next_Maintenance = intnx('month',Last_Maint_Date,3,'same');
run;
proc print data=smart_parking_clean;
run;
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score | Occupied_Slots | Utilization_Percent | Parking_Name | Months_Operational | Next_Maintenance |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 |
| 2 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 |
| 3 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 |
| 4 | P004 | Bengaluru | Low | 05JAN2024 | 01FEB2024 | 120 | 0 | 7 | 18000 | 90 | . | . | BENGALURU_P004 | 26 | 23497 |
| 5 | P005 | Chennai | High | 01APR2024 | 01APR2024 | 80 | 95 | 3 | 12000 | 95 | 76 | 95.0 | CHENNAI_P005 | 23 | 23558 |
| 6 | P006 | Pune | Low | 01JAN2024 | 15JAN2024 | 60 | 45 | 8 | 8000 | 70 | 27 | 45.0 | PUNE_P006 | 26 | 23481 |
| 7 | P007 | Hyderabad | High | 01JAN2024 | 01FEB2024 | 90 | 100 | 2 | 20000 | 99 | 90 | 100.0 | HYDERABAD_P007 | 26 | 23497 |
| 8 | P008 | Mumbai | Medium | 01MAR2024 | 01MAR2024 | 110 | 60 | 9 | 17000 | 85 | 66 | 60.0 | MUMBAI_P008 | 24 | 23528 |
| 9 | P009 | Delhi | Medium | 01JAN2024 | 01APR2024 | 140 | 70 | 10 | 21000 | 87 | 98 | 70.0 | DELHI_P009 | 26 | 23558 |
| 10 | P010 | Bengaluru | High | 01FEB2024 | 01MAR2024 | 130 | 85 | 6 | 22000 | 93 | 111 | 85.4 | BENGALURU_P010 | 25 | 23528 |
| 11 | P011 | Chennai | Low | 01JAN2024 | 01JAN2024 | 95 | 50 | 12 | 5000 | 60 | 48 | 50.5 | CHENNAI_P011 | 26 | 23467 |
| 12 | P012 | Pune | Low | 01JAN2024 | 10JAN2024 | 75 | 40 | 15 | 4000 | 55 | 30 | 40.0 | PUNE_P012 | 26 | 23476 |
| 13 | P013 | Hyderabad | High | 01JAN2024 | 01APR2024 | 200 | 180 | 3 | 50000 | 98 | 200 | 100.0 | HYDERABAD_P013 | 26 | 23558 |
| 14 | P014 | Mumbai | Low | 01JAN2024 | 01JAN2024 | 100 | 0 | 20 | 0 | 20 | 0 | 0.0 | MUMBAI_P014 | 26 | 23467 |
| 15 | P015 | Delhi | High | 01JAN2024 | 01MAR2024 | 160 | 150 | 4 | 45000 | 96 | 160 | 100.0 | DELHI_P015 | 26 | 23528 |
set
smart_parking_raw;
Reads previous dataset into new dataset.
propcase(strip(City));\
·
strip( )
removes spaces
·
propcase(
) standardizes case
round()
Prevents decimal slot calculation.
intck()
Counts number of months between two dates.
intnx()
Adds 3 months for next maintenance.
3. FRAUD DETECTION MACRO
%macro fraud_detection(ds);
data fraud_flagged;
set &ds;
length Fraud_Flag $10;
if Revenue > 40000 and Utilization_Percent < 50 then Fraud_Flag="Yes";
else if Occupied_Slots = Slots_Total and Avg_Search_Time < 2 then Fraud_Flag="Yes";
else Fraud_Flag="No";
run;
proc print data=fraud_flagged;
run;
%mend;
%fraud_detection(smart_parking_clean);
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score | Occupied_Slots | Utilization_Percent | Parking_Name | Months_Operational | Next_Maintenance | Fraud_Flag |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 | No |
| 2 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 | No |
| 3 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 | No |
| 4 | P004 | Bengaluru | Low | 05JAN2024 | 01FEB2024 | 120 | 0 | 7 | 18000 | 90 | . | . | BENGALURU_P004 | 26 | 23497 | No |
| 5 | P005 | Chennai | High | 01APR2024 | 01APR2024 | 80 | 95 | 3 | 12000 | 95 | 76 | 95.0 | CHENNAI_P005 | 23 | 23558 | No |
| 6 | P006 | Pune | Low | 01JAN2024 | 15JAN2024 | 60 | 45 | 8 | 8000 | 70 | 27 | 45.0 | PUNE_P006 | 26 | 23481 | No |
| 7 | P007 | Hyderabad | High | 01JAN2024 | 01FEB2024 | 90 | 100 | 2 | 20000 | 99 | 90 | 100.0 | HYDERABAD_P007 | 26 | 23497 | No |
| 8 | P008 | Mumbai | Medium | 01MAR2024 | 01MAR2024 | 110 | 60 | 9 | 17000 | 85 | 66 | 60.0 | MUMBAI_P008 | 24 | 23528 | No |
| 9 | P009 | Delhi | Medium | 01JAN2024 | 01APR2024 | 140 | 70 | 10 | 21000 | 87 | 98 | 70.0 | DELHI_P009 | 26 | 23558 | No |
| 10 | P010 | Bengaluru | High | 01FEB2024 | 01MAR2024 | 130 | 85 | 6 | 22000 | 93 | 111 | 85.4 | BENGALURU_P010 | 25 | 23528 | No |
| 11 | P011 | Chennai | Low | 01JAN2024 | 01JAN2024 | 95 | 50 | 12 | 5000 | 60 | 48 | 50.5 | CHENNAI_P011 | 26 | 23467 | No |
| 12 | P012 | Pune | Low | 01JAN2024 | 10JAN2024 | 75 | 40 | 15 | 4000 | 55 | 30 | 40.0 | PUNE_P012 | 26 | 23476 | No |
| 13 | P013 | Hyderabad | High | 01JAN2024 | 01APR2024 | 200 | 180 | 3 | 50000 | 98 | 200 | 100.0 | HYDERABAD_P013 | 26 | 23558 | No |
| 14 | P014 | Mumbai | Low | 01JAN2024 | 01JAN2024 | 100 | 0 | 20 | 0 | 20 | 0 | 0.0 | MUMBAI_P014 | 26 | 23467 | No |
| 15 | P015 | Delhi | High | 01JAN2024 | 01MAR2024 | 160 | 150 | 4 | 45000 | 96 | 160 | 100.0 | DELHI_P015 | 26 | 23528 | No |
4. APPEND
data new_entry;
set smart_parking_clean(obs=3);
run;
proc print data=new_entry;
run;
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score | Occupied_Slots | Utilization_Percent | Parking_Name | Months_Operational | Next_Maintenance |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 |
| 2 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 |
| 3 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 |
proc append base=smart_parking_clean
data=new_entry force;
run;
proc print data=smart_parking_clean;
run;
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score | Occupied_Slots | Utilization_Percent | Parking_Name | Months_Operational | Next_Maintenance |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 |
| 2 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 |
| 3 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 |
| 4 | P004 | Bengaluru | Low | 05JAN2024 | 01FEB2024 | 120 | 0 | 7 | 18000 | 90 | . | . | BENGALURU_P004 | 26 | 23497 |
| 5 | P005 | Chennai | High | 01APR2024 | 01APR2024 | 80 | 95 | 3 | 12000 | 95 | 76 | 95.0 | CHENNAI_P005 | 23 | 23558 |
| 6 | P006 | Pune | Low | 01JAN2024 | 15JAN2024 | 60 | 45 | 8 | 8000 | 70 | 27 | 45.0 | PUNE_P006 | 26 | 23481 |
| 7 | P007 | Hyderabad | High | 01JAN2024 | 01FEB2024 | 90 | 100 | 2 | 20000 | 99 | 90 | 100.0 | HYDERABAD_P007 | 26 | 23497 |
| 8 | P008 | Mumbai | Medium | 01MAR2024 | 01MAR2024 | 110 | 60 | 9 | 17000 | 85 | 66 | 60.0 | MUMBAI_P008 | 24 | 23528 |
| 9 | P009 | Delhi | Medium | 01JAN2024 | 01APR2024 | 140 | 70 | 10 | 21000 | 87 | 98 | 70.0 | DELHI_P009 | 26 | 23558 |
| 10 | P010 | Bengaluru | High | 01FEB2024 | 01MAR2024 | 130 | 85 | 6 | 22000 | 93 | 111 | 85.4 | BENGALURU_P010 | 25 | 23528 |
| 11 | P011 | Chennai | Low | 01JAN2024 | 01JAN2024 | 95 | 50 | 12 | 5000 | 60 | 48 | 50.5 | CHENNAI_P011 | 26 | 23467 |
| 12 | P012 | Pune | Low | 01JAN2024 | 10JAN2024 | 75 | 40 | 15 | 4000 | 55 | 30 | 40.0 | PUNE_P012 | 26 | 23476 |
| 13 | P013 | Hyderabad | High | 01JAN2024 | 01APR2024 | 200 | 180 | 3 | 50000 | 98 | 200 | 100.0 | HYDERABAD_P013 | 26 | 23558 |
| 14 | P014 | Mumbai | Low | 01JAN2024 | 01JAN2024 | 100 | 0 | 20 | 0 | 20 | 0 | 0.0 | MUMBAI_P014 | 26 | 23467 |
| 15 | P015 | Delhi | High | 01JAN2024 | 01MAR2024 | 160 | 150 | 4 | 45000 | 96 | 160 | 100.0 | DELHI_P015 | 26 | 23528 |
| 16 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 |
| 17 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 |
| 18 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 |
5. MERGE
data city_target;
input City:$20. Target_Revenue;
datalines;
Hyderabad 20000
Mumbai 30000
Delhi 25000
;
run;
proc print data=city_target;
run;
OUTPUT:
| Obs | City | Target_Revenue |
|---|---|---|
| 1 | Hyderabad | 20000 |
| 2 | Mumbai | 30000 |
| 3 | Delhi | 25000 |
proc sort data=smart_parking_clean; by City; run;
proc print data=smart_parking_clean;
run;
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score | Occupied_Slots | Utilization_Percent | Parking_Name | Months_Operational | Next_Maintenance |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P004 | Bengaluru | Low | 05JAN2024 | 01FEB2024 | 120 | 0 | 7 | 18000 | 90 | . | . | BENGALURU_P004 | 26 | 23497 |
| 2 | P010 | Bengaluru | High | 01FEB2024 | 01MAR2024 | 130 | 85 | 6 | 22000 | 93 | 111 | 85.4 | BENGALURU_P010 | 25 | 23528 |
| 3 | P005 | Chennai | High | 01APR2024 | 01APR2024 | 80 | 95 | 3 | 12000 | 95 | 76 | 95.0 | CHENNAI_P005 | 23 | 23558 |
| 4 | P011 | Chennai | Low | 01JAN2024 | 01JAN2024 | 95 | 50 | 12 | 5000 | 60 | 48 | 50.5 | CHENNAI_P011 | 26 | 23467 |
| 5 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 |
| 6 | P009 | Delhi | Medium | 01JAN2024 | 01APR2024 | 140 | 70 | 10 | 21000 | 87 | 98 | 70.0 | DELHI_P009 | 26 | 23558 |
| 7 | P015 | Delhi | High | 01JAN2024 | 01MAR2024 | 160 | 150 | 4 | 45000 | 96 | 160 | 100.0 | DELHI_P015 | 26 | 23528 |
| 8 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 |
| 9 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 |
| 10 | P007 | Hyderabad | High | 01JAN2024 | 01FEB2024 | 90 | 100 | 2 | 20000 | 99 | 90 | 100.0 | HYDERABAD_P007 | 26 | 23497 |
| 11 | P013 | Hyderabad | High | 01JAN2024 | 01APR2024 | 200 | 180 | 3 | 50000 | 98 | 200 | 100.0 | HYDERABAD_P013 | 26 | 23558 |
| 12 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 |
| 13 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 |
| 14 | P008 | Mumbai | Medium | 01MAR2024 | 01MAR2024 | 110 | 60 | 9 | 17000 | 85 | 66 | 60.0 | MUMBAI_P008 | 24 | 23528 |
| 15 | P014 | Mumbai | Low | 01JAN2024 | 01JAN2024 | 100 | 0 | 20 | 0 | 20 | 0 | 0.0 | MUMBAI_P014 | 26 | 23467 |
| 16 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 |
| 17 | P006 | Pune | Low | 01JAN2024 | 15JAN2024 | 60 | 45 | 8 | 8000 | 70 | 27 | 45.0 | PUNE_P006 | 26 | 23481 |
| 18 | P012 | Pune | Low | 01JAN2024 | 10JAN2024 | 75 | 40 | 15 | 4000 | 55 | 30 | 40.0 | PUNE_P012 | 26 | 23476 |
proc sort data=city_target; by City; run;
proc print data=city_target;
run;
OUTPUT:
| Obs | City | Target_Revenue |
|---|---|---|
| 1 | Delhi | 25000 |
| 2 | Hyderabad | 20000 |
| 3 | Mumbai | 30000 |
data merged_data;
merge smart_parking_clean city_target;
by City;
run;
proc print data=merged_data;
run;
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score | Occupied_Slots | Utilization_Percent | Parking_Name | Months_Operational | Next_Maintenance | Target_Revenue |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P004 | Bengaluru | Low | 05JAN2024 | 01FEB2024 | 120 | 0 | 7 | 18000 | 90 | . | . | BENGALURU_P004 | 26 | 23497 | . |
| 2 | P010 | Bengaluru | High | 01FEB2024 | 01MAR2024 | 130 | 85 | 6 | 22000 | 93 | 111 | 85.4 | BENGALURU_P010 | 25 | 23528 | . |
| 3 | P005 | Chennai | High | 01APR2024 | 01APR2024 | 80 | 95 | 3 | 12000 | 95 | 76 | 95.0 | CHENNAI_P005 | 23 | 23558 | . |
| 4 | P011 | Chennai | Low | 01JAN2024 | 01JAN2024 | 95 | 50 | 12 | 5000 | 60 | 48 | 50.5 | CHENNAI_P011 | 26 | 23467 | . |
| 5 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 | 25000 |
| 6 | P009 | Delhi | Medium | 01JAN2024 | 01APR2024 | 140 | 70 | 10 | 21000 | 87 | 98 | 70.0 | DELHI_P009 | 26 | 23558 | 25000 |
| 7 | P015 | Delhi | High | 01JAN2024 | 01MAR2024 | 160 | 150 | 4 | 45000 | 96 | 160 | 100.0 | DELHI_P015 | 26 | 23528 | 25000 |
| 8 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 | 25000 |
| 9 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 | 20000 |
| 10 | P007 | Hyderabad | High | 01JAN2024 | 01FEB2024 | 90 | 100 | 2 | 20000 | 99 | 90 | 100.0 | HYDERABAD_P007 | 26 | 23497 | 20000 |
| 11 | P013 | Hyderabad | High | 01JAN2024 | 01APR2024 | 200 | 180 | 3 | 50000 | 98 | 200 | 100.0 | HYDERABAD_P013 | 26 | 23558 | 20000 |
| 12 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 | 20000 |
| 13 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 | 30000 |
| 14 | P008 | Mumbai | Medium | 01MAR2024 | 01MAR2024 | 110 | 60 | 9 | 17000 | 85 | 66 | 60.0 | MUMBAI_P008 | 24 | 23528 | 30000 |
| 15 | P014 | Mumbai | Low | 01JAN2024 | 01JAN2024 | 100 | 0 | 20 | 0 | 20 | 0 | 0.0 | MUMBAI_P014 | 26 | 23467 | 30000 |
| 16 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 | 30000 |
| 17 | P006 | Pune | Low | 01JAN2024 | 15JAN2024 | 60 | 45 | 8 | 8000 | 70 | 27 | 45.0 | PUNE_P006 | 26 | 23481 | . |
| 18 | P012 | Pune | Low | 01JAN2024 | 10JAN2024 | 75 | 40 | 15 | 4000 | 55 | 30 | 40.0 | PUNE_P012 | 26 | 23476 | . |
6. TRANSPOSE
proc sort data=smart_parking_clean; by City; run;
proc print data=smart_parking_clean;
run;
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score | Occupied_Slots | Utilization_Percent | Parking_Name | Months_Operational | Next_Maintenance |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P004 | Bengaluru | Low | 05JAN2024 | 01FEB2024 | 120 | 0 | 7 | 18000 | 90 | . | . | BENGALURU_P004 | 26 | 23497 |
| 2 | P010 | Bengaluru | High | 01FEB2024 | 01MAR2024 | 130 | 85 | 6 | 22000 | 93 | 111 | 85.4 | BENGALURU_P010 | 25 | 23528 |
| 3 | P005 | Chennai | High | 01APR2024 | 01APR2024 | 80 | 95 | 3 | 12000 | 95 | 76 | 95.0 | CHENNAI_P005 | 23 | 23558 |
| 4 | P011 | Chennai | Low | 01JAN2024 | 01JAN2024 | 95 | 50 | 12 | 5000 | 60 | 48 | 50.5 | CHENNAI_P011 | 26 | 23467 |
| 5 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 |
| 6 | P009 | Delhi | Medium | 01JAN2024 | 01APR2024 | 140 | 70 | 10 | 21000 | 87 | 98 | 70.0 | DELHI_P009 | 26 | 23558 |
| 7 | P015 | Delhi | High | 01JAN2024 | 01MAR2024 | 160 | 150 | 4 | 45000 | 96 | 160 | 100.0 | DELHI_P015 | 26 | 23528 |
| 8 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 |
| 9 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 |
| 10 | P007 | Hyderabad | High | 01JAN2024 | 01FEB2024 | 90 | 100 | 2 | 20000 | 99 | 90 | 100.0 | HYDERABAD_P007 | 26 | 23497 |
| 11 | P013 | Hyderabad | High | 01JAN2024 | 01APR2024 | 200 | 180 | 3 | 50000 | 98 | 200 | 100.0 | HYDERABAD_P013 | 26 | 23558 |
| 12 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 |
| 13 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 |
| 14 | P008 | Mumbai | Medium | 01MAR2024 | 01MAR2024 | 110 | 60 | 9 | 17000 | 85 | 66 | 60.0 | MUMBAI_P008 | 24 | 23528 |
| 15 | P014 | Mumbai | Low | 01JAN2024 | 01JAN2024 | 100 | 0 | 20 | 0 | 20 | 0 | 0.0 | MUMBAI_P014 | 26 | 23467 |
| 16 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 |
| 17 | P006 | Pune | Low | 01JAN2024 | 15JAN2024 | 60 | 45 | 8 | 8000 | 70 | 27 | 45.0 | PUNE_P006 | 26 | 23481 |
| 18 | P012 | Pune | Low | 01JAN2024 | 10JAN2024 | 75 | 40 | 15 | 4000 | 55 | 30 | 40.0 | PUNE_P012 | 26 | 23476 |
proc transpose data=smart_parking_clean out=transposed;
by City;
var Revenue Utilization_Percent;
run;
proc print data=transposed;
run;
OUTPUT:
| Obs | City | _NAME_ | COL1 | COL2 | COL3 | COL4 |
|---|---|---|---|---|---|---|
| 1 | Bengaluru | Revenue | 18000.0 | 22000.0 | . | . |
| 2 | Bengaluru | Utilization_Percent | . | 85.4 | . | . |
| 3 | Chennai | Revenue | 12000.0 | 5000.0 | . | . |
| 4 | Chennai | Utilization_Percent | 95.0 | 50.5 | . | . |
| 5 | Delhi | Revenue | 0.0 | 21000.0 | 45000 | 0.0 |
| 6 | Delhi | Utilization_Percent | 75.3 | 70.0 | 100 | 75.3 |
| 7 | Hyderabad | Revenue | 15000.0 | 20000.0 | 50000 | 15000.0 |
| 8 | Hyderabad | Utilization_Percent | 85.0 | 100.0 | 100 | 85.0 |
| 9 | Mumbai | Revenue | 30000.0 | 17000.0 | 0 | 30000.0 |
| 10 | Mumbai | Utilization_Percent | 100.0 | 60.0 | 0 | 100.0 |
| 11 | Pune | Revenue | 8000.0 | 4000.0 | . | . |
| 12 | Pune | Utilization_Percent | 45.0 | 40.0 | . | . |
7. PROC DATASETS DELETE
proc datasets library=work;
delete smart_parking_raw;
quit;
LOG:
8. PROC SQL ANALYSIS
proc sql;
create table revenue_summary as
select City,
sum(Revenue) as Total_Revenue,
mean(Utilization_Percent) as Avg_Util
from smart_parking_clean
group by City;
quit;
proc print data=revenue_summary;
run;
OUTPUT:
| Obs | City | Total_Revenue | Avg_Util |
|---|---|---|---|
| 1 | Bengaluru | 40000 | 85.40 |
| 2 | Chennai | 17000 | 72.75 |
| 3 | Delhi | 66000 | 80.15 |
| 4 | Hyderabad | 100000 | 92.50 |
| 5 | Mumbai | 77000 | 65.00 |
| 6 | Pune | 12000 | 42.50 |
9. Sensor-Level Dataset
data sensor_data;
length Sensor_ID $6 Parking_ID $5 Status $10;
format Event_Time datetime20.;
input Sensor_ID $ Parking_ID $ Status $ Event_Time :datetime20.;
datalines;
S001 P001 Occupied 01JAN2024:10:15:00
S002 P001 Free 01JAN2024:10:16:00
S003 P002 Occupied 01JAN2024:10:17:00
S004 P003 Error 01JAN2024:10:18:00
S005 P004 Occupied 01JAN2024:10:19:00
;
run;
proc print data=sensor_data;
run;
OUTPUT:
| Obs | Sensor_ID | Parking_ID | Status | Event_Time |
|---|---|---|---|---|
| 1 | S001 | P001 | Occupied | 01JAN2024:10:15:00 |
| 2 | S002 | P001 | Free | 01JAN2024:10:16:00 |
| 3 | S003 | P002 | Occupied | 01JAN2024:10:17:00 |
| 4 | S004 | P003 | Error | 01JAN2024:10:18:00 |
| 5 | S005 | P004 | Occupied | 01JAN2024:10:19:00 |
·
Sensor malfunction
·
Ghost occupancy
·
Delayed updates
·
Duplicate events
10. Payment Transaction Dataset
data transactions;
length Trans_ID $6 Parking_ID $5 Payment_Mode $10;
format Payment_Date datetime20.;
input Trans_ID $ Parking_ID $ Amount Payment_Mode $ Payment_Date :datetime20.;
datalines;
T001 P001 200 UPI 01JAN2024:10:20:00
T002 P001 200 Card 01JAN2024:10:21:00
T003 P002 500 Cash 01JAN2024:10:22:00
T004 P003 1000 UPI 01JAN2024:10:23:00
T005 P014 0 Cash 01JAN2024:10:24:00
;
run;
proc print data=transactions;
run;
OUTPUT:
| Obs | Trans_ID | Parking_ID | Payment_Mode | Payment_Date | Amount |
|---|---|---|---|---|---|
| 1 | T001 | P001 | UPI | 01JAN2024:10:20:00 | 200 |
| 2 | T002 | P001 | Card | 01JAN2024:10:21:00 | 200 |
| 3 | T003 | P002 | Cash | 01JAN2024:10:22:00 | 500 |
| 4 | T004 | P003 | UPI | 01JAN2024:10:23:00 | 1000 |
| 5 | T005 | P014 | Cash | 01JAN2024:10:24:00 | 0 |
11. Revenue Reconciliation Logic
proc sql;
create table reconciliation as
select a.Parking_ID,
count(b.Trans_ID) as Payment_Count,
sum(b.Amount) as Collected_Revenue,
a.Occupied_Slots,
(a.Occupied_Slots * 200) as Expected_Revenue
from smart_parking_clean a
left join transactions b
on a.Parking_ID = b.Parking_ID
group by a.Parking_ID;
quit;
proc print data=reconciliation;
run;
OUTPUT:
| Obs | Parking_ID | Payment_Count | Collected_Revenue | Occupied_Slots | Expected_Revenue |
|---|---|---|---|---|---|
| 1 | P001 | 4 | 800 | 85 | 17000 |
| 2 | P001 | 4 | 800 | 85 | 17000 |
| 3 | P001 | 4 | 800 | 85 | 17000 |
| 4 | P001 | 4 | 800 | 85 | 17000 |
| 5 | P002 | 2 | 1000 | 200 | 40000 |
| 6 | P002 | 2 | 1000 | 200 | 40000 |
| 7 | P003 | 2 | 2000 | 113 | 22600 |
| 8 | P003 | 2 | 2000 | 113 | 22600 |
| 9 | P004 | 0 | . | . | . |
| 10 | P005 | 0 | . | 76 | 15200 |
| 11 | P006 | 0 | . | 27 | 5400 |
| 12 | P007 | 0 | . | 90 | 18000 |
| 13 | P008 | 0 | . | 66 | 13200 |
| 14 | P009 | 0 | . | 98 | 19600 |
| 15 | P010 | 0 | . | 111 | 22200 |
| 16 | P011 | 0 | . | 48 | 9600 |
| 17 | P012 | 0 | . | 30 | 6000 |
| 18 | P013 | 0 | . | 200 | 40000 |
| 19 | P014 | 1 | 0 | 0 | 0 |
| 20 | P015 | 0 | . | 160 | 32000 |
·
Occupied Slots vs Transactions
·
Revenue vs Expected Revenue
12. Fraud Indicator
data reconciliation_flag;
set reconciliation;
if Collected_Revenue < Expected_Revenue then Revenue_Leak="Yes";
else Revenue_Leak="No";
run;
proc print data=reconciliation_flag;
run;
OUTPUT:
| Obs | Parking_ID | Payment_Count | Collected_Revenue | Occupied_Slots | Expected_Revenue | Revenue_Leak |
|---|---|---|---|---|---|---|
| 1 | P001 | 4 | 800 | 85 | 17000 | Yes |
| 2 | P001 | 4 | 800 | 85 | 17000 | Yes |
| 3 | P001 | 4 | 800 | 85 | 17000 | Yes |
| 4 | P001 | 4 | 800 | 85 | 17000 | Yes |
| 5 | P002 | 2 | 1000 | 200 | 40000 | Yes |
| 6 | P002 | 2 | 1000 | 200 | 40000 | Yes |
| 7 | P003 | 2 | 2000 | 113 | 22600 | Yes |
| 8 | P003 | 2 | 2000 | 113 | 22600 | Yes |
| 9 | P004 | 0 | . | . | . | No |
| 10 | P005 | 0 | . | 76 | 15200 | Yes |
| 11 | P006 | 0 | . | 27 | 5400 | Yes |
| 12 | P007 | 0 | . | 90 | 18000 | Yes |
| 13 | P008 | 0 | . | 66 | 13200 | Yes |
| 14 | P009 | 0 | . | 98 | 19600 | Yes |
| 15 | P010 | 0 | . | 111 | 22200 | Yes |
| 16 | P011 | 0 | . | 48 | 9600 | Yes |
| 17 | P012 | 0 | . | 30 | 6000 | Yes |
| 18 | P013 | 0 | . | 200 | 40000 | Yes |
| 19 | P014 | 1 | 0 | 0 | 0 | No |
| 20 | P015 | 0 | . | 160 | 32000 | Yes |
·
Use WHERE instead of IF
·
Avoid unnecessary SORT
·
Use HASH joins for speed
·
Use KEEP and DROP
13. Advanced Fraud Scoring Model
data fraud_score;
set reconciliation_flag;
Score = 0;
if Revenue_Leak="Yes" then Score+40;
if Payment_Count < Occupied_Slots then Score+30;
if Expected_Revenue > 40000 and Collected_Revenue < 20000 then Score+20;
if Occupied_Slots = Slots_Total then Score+10;
if Score >=60 then Risk_Level="High";
else if Score>=30 then Risk_Level="Medium";
else Risk_Level="Low";
run;
proc print data=fraud_score;
run;
OUTPUT:
| Obs | Parking_ID | Payment_Count | Collected_Revenue | Occupied_Slots | Expected_Revenue | Revenue_Leak | Score | Slots_Total | Risk_Level |
|---|---|---|---|---|---|---|---|---|---|
| 1 | P001 | 4 | 800 | 85 | 17000 | Yes | 70 | . | High |
| 2 | P001 | 4 | 800 | 85 | 17000 | Yes | 70 | . | High |
| 3 | P001 | 4 | 800 | 85 | 17000 | Yes | 70 | . | High |
| 4 | P001 | 4 | 800 | 85 | 17000 | Yes | 70 | . | High |
| 5 | P002 | 2 | 1000 | 200 | 40000 | Yes | 70 | . | High |
| 6 | P002 | 2 | 1000 | 200 | 40000 | Yes | 70 | . | High |
| 7 | P003 | 2 | 2000 | 113 | 22600 | Yes | 70 | . | High |
| 8 | P003 | 2 | 2000 | 113 | 22600 | Yes | 70 | . | High |
| 9 | P004 | 0 | . | . | . | No | 10 | . | Low |
| 10 | P005 | 0 | . | 76 | 15200 | Yes | 70 | . | High |
| 11 | P006 | 0 | . | 27 | 5400 | Yes | 70 | . | High |
| 12 | P007 | 0 | . | 90 | 18000 | Yes | 70 | . | High |
| 13 | P008 | 0 | . | 66 | 13200 | Yes | 70 | . | High |
| 14 | P009 | 0 | . | 98 | 19600 | Yes | 70 | . | High |
| 15 | P010 | 0 | . | 111 | 22200 | Yes | 70 | . | High |
| 16 | P011 | 0 | . | 48 | 9600 | Yes | 70 | . | High |
| 17 | P012 | 0 | . | 30 | 6000 | Yes | 70 | . | High |
| 18 | P013 | 0 | . | 200 | 40000 | Yes | 70 | . | High |
| 19 | P014 | 1 | 0 | 0 | 0 | No | 0 | . | Low |
| 20 | P015 | 0 | . | 160 | 32000 | Yes | 70 | . | High |
14. Efficiency KPI Framework
data kpi_engine;
set smart_parking_clean;
Revenue_Per_Slot = Revenue / Slots_Total;
Search_Time_Index = Avg_Search_Time / 10;
Utilization_Index = Utilization_Percent / 100;
Composite_Efficiency = round((Revenue_Per_Slot*0.4 +
Utilization_Index*0.4 -
Search_Time_Index*0.2)*100,0.1);
run;
proc print data=kpi_engine;
run;
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score | Occupied_Slots | Utilization_Percent | Parking_Name | Months_Operational | Next_Maintenance | Revenue_Per_Slot | Search_Time_Index | Utilization_Index | Composite_Efficiency |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P004 | Bengaluru | Low | 05JAN2024 | 01FEB2024 | 120 | 0 | 7 | 18000 | 90 | . | . | BENGALURU_P004 | 26 | 23497 | 150.000 | 0.7 | . | . |
| 2 | P010 | Bengaluru | High | 01FEB2024 | 01MAR2024 | 130 | 85 | 6 | 22000 | 93 | 111 | 85.4 | BENGALURU_P010 | 25 | 23528 | 169.231 | 0.6 | 0.854 | 6791.4 |
| 3 | P005 | Chennai | High | 01APR2024 | 01APR2024 | 80 | 95 | 3 | 12000 | 95 | 76 | 95.0 | CHENNAI_P005 | 23 | 23558 | 150.000 | 0.3 | 0.950 | 6032.0 |
| 4 | P011 | Chennai | Low | 01JAN2024 | 01JAN2024 | 95 | 50 | 12 | 5000 | 60 | 48 | 50.5 | CHENNAI_P011 | 26 | 23467 | 52.632 | 1.2 | 0.505 | 2101.5 |
| 5 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 | 0.000 | 0.6 | 0.753 | 18.1 |
| 6 | P009 | Delhi | Medium | 01JAN2024 | 01APR2024 | 140 | 70 | 10 | 21000 | 87 | 98 | 70.0 | DELHI_P009 | 26 | 23558 | 150.000 | 1.0 | 0.700 | 6008.0 |
| 7 | P015 | Delhi | High | 01JAN2024 | 01MAR2024 | 160 | 150 | 4 | 45000 | 96 | 160 | 100.0 | DELHI_P015 | 26 | 23528 | 281.250 | 0.4 | 1.000 | 11282.0 |
| 8 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 | 0.000 | 0.6 | 0.753 | 18.1 |
| 9 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 | 150.000 | 0.5 | 0.850 | 6024.0 |
| 10 | P007 | Hyderabad | High | 01JAN2024 | 01FEB2024 | 90 | 100 | 2 | 20000 | 99 | 90 | 100.0 | HYDERABAD_P007 | 26 | 23497 | 222.222 | 0.2 | 1.000 | 8924.9 |
| 11 | P013 | Hyderabad | High | 01JAN2024 | 01APR2024 | 200 | 180 | 3 | 50000 | 98 | 200 | 100.0 | HYDERABAD_P013 | 26 | 23558 | 250.000 | 0.3 | 1.000 | 10034.0 |
| 12 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 | 150.000 | 0.5 | 0.850 | 6024.0 |
| 13 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 | 150.000 | 0.4 | 1.000 | 6032.0 |
| 14 | P008 | Mumbai | Medium | 01MAR2024 | 01MAR2024 | 110 | 60 | 9 | 17000 | 85 | 66 | 60.0 | MUMBAI_P008 | 24 | 23528 | 154.545 | 0.9 | 0.600 | 6187.8 |
| 15 | P014 | Mumbai | Low | 01JAN2024 | 01JAN2024 | 100 | 0 | 20 | 0 | 20 | 0 | 0.0 | MUMBAI_P014 | 26 | 23467 | 0.000 | 2.0 | 0.000 | -40.0 |
| 16 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 | 150.000 | 0.4 | 1.000 | 6032.0 |
| 17 | P006 | Pune | Low | 01JAN2024 | 15JAN2024 | 60 | 45 | 8 | 8000 | 70 | 27 | 45.0 | PUNE_P006 | 26 | 23481 | 133.333 | 0.8 | 0.450 | 5335.3 |
| 18 | P012 | Pune | Low | 01JAN2024 | 10JAN2024 | 75 | 40 | 15 | 4000 | 55 | 30 | 40.0 | PUNE_P012 | 26 | 23476 | 53.333 | 1.5 | 0.400 | 2119.3 |
15. Real-Time Utilization Engine
proc sql;
create table live_utilization as
select Parking_ID,
count(case when Status="Occupied" then 1 end) as Live_Occupied,
calculated Live_Occupied / 100 * 100 as Live_Utilization
from sensor_data
group by Parking_ID;
quit;
proc print data=live_utilization;
run;
OUTPUT:
| Obs | Parking_ID | Live_Occupied | Live_Utilization |
|---|---|---|---|
| 1 | P001 | 1 | 1 |
| 2 | P002 | 1 | 1 |
| 3 | P003 | 0 | 0 |
| 4 | P004 | 1 | 1 |
16. Predictive Maintenance Engine
data maintenance_risk;
set smart_parking_clean;
Days_Since_Maint = intck('day',Last_Maint_Date,today());
if Days_Since_Maint > 90 then Maint_Risk="High";
else if Days_Since_Maint >60 then Maint_Risk="Medium";
else Maint_Risk="Low";
run;
proc print data=maintenance_risk;
run;
OUTPUT:
| Obs | Parking_ID | City | Util_Class | Install_Date | Last_Maint_Date | Slots_Total | Occupancy_Rate | Avg_Search_Time | Revenue | Efficiency_Score | Occupied_Slots | Utilization_Percent | Parking_Name | Months_Operational | Next_Maintenance | Days_Since_Maint | Maint_Risk |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | P004 | Bengaluru | Low | 05JAN2024 | 01FEB2024 | 120 | 0 | 7 | 18000 | 90 | . | . | BENGALURU_P004 | 26 | 23497 | 761 | High |
| 2 | P010 | Bengaluru | High | 01FEB2024 | 01MAR2024 | 130 | 85 | 6 | 22000 | 93 | 111 | 85.4 | BENGALURU_P010 | 25 | 23528 | 732 | High |
| 3 | P005 | Chennai | High | 01APR2024 | 01APR2024 | 80 | 95 | 3 | 12000 | 95 | 76 | 95.0 | CHENNAI_P005 | 23 | 23558 | 701 | High |
| 4 | P011 | Chennai | Low | 01JAN2024 | 01JAN2024 | 95 | 50 | 12 | 5000 | 60 | 48 | 50.5 | CHENNAI_P011 | 26 | 23467 | 792 | High |
| 5 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 | 723 | High |
| 6 | P009 | Delhi | Medium | 01JAN2024 | 01APR2024 | 140 | 70 | 10 | 21000 | 87 | 98 | 70.0 | DELHI_P009 | 26 | 23558 | 701 | High |
| 7 | P015 | Delhi | High | 01JAN2024 | 01MAR2024 | 160 | 150 | 4 | 45000 | 96 | 160 | 100.0 | DELHI_P015 | 26 | 23528 | 732 | High |
| 8 | P003 | Delhi | Medium | 01MAR2024 | 10MAR2024 | 150 | 75 | 6 | 0 | 88 | 113 | 75.3 | DELHI_P003 | 24 | 23537 | 723 | High |
| 9 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 | 732 | High |
| 10 | P007 | Hyderabad | High | 01JAN2024 | 01FEB2024 | 90 | 100 | 2 | 20000 | 99 | 90 | 100.0 | HYDERABAD_P007 | 26 | 23497 | 761 | High |
| 11 | P013 | Hyderabad | High | 01JAN2024 | 01APR2024 | 200 | 180 | 3 | 50000 | 98 | 200 | 100.0 | HYDERABAD_P013 | 26 | 23558 | 701 | High |
| 12 | P001 | Hyderabad | High | 01JAN2024 | 01MAR2024 | 100 | 85 | 5 | 15000 | 92 | 85 | 85.0 | HYDERABAD_P001 | 26 | 23528 | 732 | High |
| 13 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 | 701 | High |
| 14 | P008 | Mumbai | Medium | 01MAR2024 | 01MAR2024 | 110 | 60 | 9 | 17000 | 85 | 66 | 60.0 | MUMBAI_P008 | 24 | 23528 | 732 | High |
| 15 | P014 | Mumbai | Low | 01JAN2024 | 01JAN2024 | 100 | 0 | 20 | 0 | 20 | 0 | 0.0 | MUMBAI_P014 | 26 | 23467 | 792 | High |
| 16 | P002 | Mumbai | High | 15FEB2024 | 01APR2024 | 200 | 110 | 4 | 30000 | 100 | 200 | 100.0 | MUMBAI_P002 | 25 | 23558 | 701 | High |
| 17 | P006 | Pune | Low | 01JAN2024 | 15JAN2024 | 60 | 45 | 8 | 8000 | 70 | 27 | 45.0 | PUNE_P006 | 26 | 23481 | 778 | High |
| 18 | P012 | Pune | Low | 01JAN2024 | 10JAN2024 | 75 | 40 | 15 | 4000 | 55 | 30 | 40.0 | PUNE_P012 | 26 | 23476 | 783 | High |
17. Data Quality Validation Framework
%macro dq_check(ds);
proc sql noprint;
select count(*) into: missing_count
from &ds
where missing(Occupancy_Rate);
quit;
%put Missing Count = &missing_count;
%mend;
%dq_check(smart_parking_clean);
LOG:
18. Audit Trail System
data audit_log;
length Process $30 Status $10;
format Timestamp datetime20.;
Process="Fraud Scoring";
Status="Completed";
Timestamp=datetime();
run;
proc print data=audit_log;
run;
OUTPUT:
| Obs | Process | Status | Timestamp |
|---|---|---|---|
| 1 | Fraud Scoring | Completed | 03MAR2026:16:59:22 |
19. Performance Optimization Techniques
proc datasets library=work;
modify smart_parking_clean;
index create Parking_ID;
quit;
LOG:
🔢 Numeric
Functions
·
ROUND
·
COALESCE
·
ABS
·
INTCK
·
INTNX
🔤 Character Functions
·
STRIP
·
TRIM
·
CAT
·
CATX
·
UPCASE
·
LOWCASE
·
PROPCASE
20 KEY POINTS ABOUT THIS PROJECT
· Created a realistic Smart Parking dataset with
more than 15 observations.
·
Introduced intentional errors such as negative revenue and occupancy
> capacity.
·
Detected data inconsistencies using conditional logic.
·
Cleaned city names using STRIP and PROPCASE functions.
·
Calculated Occupied_Slots using ROUND numeric function.
·
Used COALESCE to handle missing values.
·
Derived Utilization_Percent and classified into High, Medium, Low.
·
Applied INTCK to compute operational months.
·
Used INTNX to schedule next maintenance.
·
Designed rule-based fraud detection macro.
·
Built revenue reconciliation between occupancy and transactions.
·
Developed a fraud scoring system instead of simple Yes/No flags.
·
Created sensor-level dataset for real-time utilization monitoring.
·
Used PROC SQL for aggregation and reconciliation.
·
Applied MERGE to integrate target revenue data.
·
Used APPEND to simulate incremental data loading.
·
Applied TRANSPOSE to reshape KPI reporting.
·
Implemented data quality macro for validation checks.
·
Created audit log dataset to track processing.
·
Optimized performance using indexing and dataset management.
SUMMARY
In this complete Smart Parking Analytics
Project, we began by designing a foundational dataset containing parking-level
metrics such as total slots, occupancy rate, revenue, search time, and
efficiency score. We intentionally inserted data errors to replicate real-world
data inconsistencies.
We then applied systematic debugging techniques using SAS DATA step logic to identify and correct these issues. Standardization techniques were applied using character functions like PROPCASE and STRIP. Numeric validations ensured revenue and efficiency scores remained within acceptable thresholds.Date functions such as MDY, INTCK, and INTNX were used to calculate operational timelines and schedule maintenance events. This added a time-based analytical layer.We developed a rule-based fraud detection macro to automatically flag suspicious records. This evolved into a more advanced fraud scoring model that assigned weighted risk levels.
The project was extended further by adding sensor-level event logs and payment transaction datasets. Revenue reconciliation logic was implemented to compare expected revenue against collected revenue. This helped detect potential financial leakage.A predictive maintenance engine calculated risk levels based on elapsed time since last service. Data quality checks were automated using macros, and audit logs were created to simulate compliance frameworks.Performance optimization techniques such as indexing and efficient SQL aggregation were incorporated to support scalability.The project demonstrates full-cycle analytics: data ingestion, cleaning, transformation, validation, fraud detection, KPI generation, and enterprise optimization.
CONCLUSION
This project proves that we can design, debug,
detect fraud, and optimize a Smart Parking ecosystem using advanced SAS
programming techniques.
The base project demonstrated strong
fundamentals:
·
Data cleaning
·
Validation
·
Utilization analytics
·
Fraud detection
·
Enterprise-grade architecture
·
Revenue reconciliation engine
·
Predictive maintenance framework
·
Sensor-based real-time monitoring
·
Data governance structure
·
Performance optimization strategy
This type of project reflects real
production-level analytical thinking. It showcases not only programming skills
but also:
·
Business understanding
·
Risk identification
·
Operational efficiency modeling
·
Strategic system design
·
Machine learning-based anomaly detection
·
Time-series revenue forecasting
·
Geo-spatial parking demand prediction
·
Cloud-based real-time analytics platform
SAS INTERVIEW QUESTIONS
· How do you handle missing values?
· What is reconciliation?
· What is log checking?
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
About the Author:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
About the Author:
SAS Learning Hub is a data analytics and SAS programming platform focused on clinical, financial, and real-world data analysis. The content is created by professionals with academic training in Pharmaceutics and hands-on experience in Base SAS, PROC SQL, Macros, SDTM, and ADaM, providing practical and industry-relevant SAS learning resources.
Disclaimer:
The datasets and analysis in this article are created for educational and demonstration purposes only. They do not represent PARKING SYSTEM data.
Our Mission:
This blog provides industry-focused SAS programming tutorials and analytics projects covering finance, healthcare, and technology.
This project is suitable for:
· Students learning SAS
· Data analysts building portfolios
· Professionals preparing for SAS interviews
· Bloggers writing about analytics
· Clinical SAS Programmer
· Research Data Analyst
· Regulatory Data Validator
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Comments
Post a Comment