Reputation: 4644
I'm attempting to recreate some code which does the opposite of what is on page 9-10 on http://support.sas.com/resources/papers/proceedings10/158-2010.pdf. So instead of making a table go from wide to long, I'd like it to become long to wide.
Id Col1 Col2
1 Val1 A
1 Val2 B
2 Val1 C
2 Val3 D
3 Val2 E
Transposes to:
Id X_Val1 X_Val2 X_Val3
1 A B .
2 C . D
3 . . E
Any ideas on how I should be going about this? I know I should be using an array and trying to create a new column X_Val1 where X_Val1 = cat('X',Val1) where X is some string.
Upvotes: 3
Views: 2905
Reputation: 63424
I have no idea why you would want to do this with anything other than PROC TRANSPOSE
.
proc transpose data=have out=want prefix='X_';
by id;
id col1;
var col2;
run;
Upvotes: 2
Reputation: 12465
You need to first figure out how many variables you need. Then you can create the variables, use an array, and assign the values.
data test;
input id col1 $ col2 $;
datalines;
1 Val1 A
1 Val2 B
2 Val3 C
2 Val4 D
2 Val5 E
;
run;
/*Need to get the number of variables that need to be created*/
proc sql noprint;
select max(c)
into :arr_size
from
( select ID, count(*) as c
from test
group by id
);
quit;
/*Get rid of leading spaces*/
%let arr_size=%left(&arr_size);
%put &arr_size;
data test_t;
set test;
by id;
/*Create the variables*/
format SOME_X1 - SOME_X&arr_size $8.;
/*Create an array*/
array SOME_X[&arr_size];
/*Retain the values*/
retain count SOME_X:;
if first.id then do;
count = 0;
do i=1 to &arr_size;
SOME_X[i] = "";
end;
end;
count = count + 1;
SOME_X[count] = col2;
if last.id then
output;
keep id SOME_X:;
run;
Upvotes: 2