Hi Folks!,     Thanks for the case study like this. Expecting more cases to practice as a SAS developer .     Happy to share ! keep learning ! Keep inspiring !     Here's my solution for the given case study :  data Tsunami;  format DATE_TIME datetime19. Regioncode id best12.;  set data.earthquakes_dirty;  id=scan(id_regioncode,1,'-');  Regioncode=scan(id_regioncode,2,'-');  FLAG_TSUNAMI=upcase(FLAG_TSUNAMI);  EQ_PRIMARY=coalesce(EQ_MAG_MW,EQ_MAG_MS,EQ_MAG_MB,EQ_MAG_ML,EQ_MAG_MFA,EQ_MAG_UNK);  DATE_TIME=dhms(mdy(month,day,year),hour,minute,seconds);  drop id_regioncode month day year hour minute seconds  EQ_MAG_MW EQ_MAG_MS EQ_MAG_MB EQ_MAG_ML EQ_MAG_MFA EQ_MAG_UNK;  run;  proc sort data=Tsunami out=Tsunami1 dupout=dup_rec nodupkey;  by id;  run;  proc sort data=Tsunami ;  by id;  run;  data valid_tsunami invalid_tsunami;  set Tsunami;  if Regioncode in (1, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90,100, 110, 120, 130, 140, 150, 160, 170)  and FLAG_TSUNAMI in (" ", "TSU")  and not missing(DATE_TIME)  and (0 <= EQ_PRIMARY <= 9.9)  and (0 <= FOCAL_DEPTH <= 700) then output valid_tsunami;  else output invalid_tsunami;  run;     data invalid_final1;  set invalid_tsunami dup_rec;  run;     proc sql;  select id into:dupid from dup_rec;  quit;  %put &=dupid;  proc sql;    create table invalid_final as  select *,  case  when REGIONCODE not in (1, 10, 15, 20, 30, 40, 50, 60, 70, 80, 90,100, 110, 120, 130, 140, 150, 160, 170) then 'Region Code'  when EQ_PRIMARY < 0 or EQ_PRIMARY > 9.9 then 'EQ Primary'  when FOCAL_DEPTH < 0 or FOCAL_DEPTH > 700 then 'Focal Depth'  when EQ_PRIMARY=. and FOCAL_DEPTH=. then 'EQ Primary, Focal Depth'  when DATE_TIME=. then 'DATE Time'  when id=&dupid then 'Duplicate ID'  end as INVALID_DESCRIPTION FORMAT=$50.  from invalid_final1;  quit; 
						
					
					... View more