Use a DO loop with SCAN() and OUTPUT to convert to a tall format dataset.
Here is a method that works even when some observations have an empty list.
data have;
input id $ state_list $50. ;
cards;
obs1 MA NE AK
obs2 NE AL ME NJ
obs3 RI
obs4 NV CA UT OR
obs5 MA NV WA CO MN MI
obs6
;
data want ;
set have;
do state_no=1 by 1 until (state_no >= countw(state_list,' '));
state=scan(state_list,state_no,' ');
output;
end;
run;
Now you can use that dataset for most things. You can even use PROC REPORT to print it in the wide style.
proc report data=want missing;
column id state,state_no;
define id / group;
define state_no / across 'STATE';
define state / group ' ';
run;
Results:
Or if you really want that wide report as a dataset use PROC TRANSPOSE
proc transpose data=want out=wide(drop=_name_) prefix=st ;
by id;
var state;
id state_no;
run;
Result: