Cleaning by creating those data sets, in my opinion, isn't particularly helpful.
I would start with something like
Proc freq data=have;
tables id*state*score / list;
run;
Which will give counts of the same combinations and show the differences near each other.
Actually and output data set could be made with the counts and filtered to only those where the count indicates a problem.
Or consider REPORTS instead of data sets
Proc tabulate data=have;
class id state ;
table id,
state
/misstext=' '
;
run;