Most of the answers so far seem to miss the OP's point -- which is that OP has a *series* variables to recode. _null_'s brilliant use of proc summary does not seem to extend nicely to multiple variables -- repeatedly running one proc summary per variable can be quite expensive if the data are large.
This kind of vector-oriented operations are, by nature, very easy to implement in vector/matrix oriented languages like R, but quite awkward for Base SAS -- IML may handle this more easily.
Below is my try using Base SAS and some macro variables. It assumes an input of two macro variables, olds and news, both are a single-blank delimited list of variable names, to recode from, and to be recoded into, respectively. The recoding is done in such a way that if there were ties in terms of frequencies, then they are broken by the value's alphabetical order. Missing values are properly propagated.
Code below is admittedly ugly at best and I am not really happy with it. I would love to post this question on sas-l to see what they can come up with.
[pre]
/* test data */
data one;
input id (v1-v5) ($);
cards;
1 a a a . a
2 a b b . a
3 a c c . a
4 b c d . a
5 b c e . a
6 c c . . a
;
run;
%let olds = v1 v2 v3 v4 v5;
%let news = n1 n2 n3 n4 n5;
ods output OneWayFreqs=freqs;
proc freq data=one order=freq;
tables &olds;
run;
ods output clear;
proc freq data=freqs;
tables table/out=levels(keep=table count);
run;
%let cOlds = %sysfunc(translate(&olds,%str(,),%str( )));
data lookup;
length name $32 value $200;
do i = 0 by 1 until (last.table);
merge freqs levels;
by table;
name = scan(table, 2);
value = coalescec(&cOlds);
target = count - i;
if (frequency > 0) then output;
end;
keep name value target frequency;
run;
data two;
set one;
if _n_ = 1 then do;
dcl hash h(dataset:"lookup");
h.definekey('name', 'value');
h.definedata('target');
h.definedone();
end;
array olds{*} $ &olds;
array news{*} &news;
do i = 1 to dim(olds);
name = vname(olds{i});
value = olds{i};
if (h.find()^=0) then target = .;
news{i} = target;
end;
keep id &olds &news;
run;
/* check */
proc print data=two noobs;
run;
/* on lst
id v1 v2 v3 v4 v5 n1 n2 n3 n4 n5
1 a a a a 3 2 5 . 1
2 a b b a 3 1 4 . 1
3 a c c a 3 3 3 . 1
4 b c d a 2 3 2 . 1
5 b c e a 2 3 1 . 1
6 c c a 1 3 . . 1
*/
[/pre]