0
votes

I have a question about transposing data without using PROC Transpose.

0   a      b     c
1  dog    cat   camel
2  9      7     2534 

Without using PROC TRANSPOSE, how can I get a resulting dataset of:

   Animals       Weight     
1  dog           9
2  cat           7
3  camel         2534
3
What's with the "How do I do what this PROC does without using it" questions? Seem like test/interview type questions... – Jon Clements♦

3 Answers

3
votes

This is a bit of a curious request. This example code is hard coded for your 3 variables. You will have to generalize this if needed.

data temp;
input a $ b $ c $; 
datalines;
dog cat camel
9 7 2534
;
run;

data animal_weight;
set temp end=last;
format animal animals1-animals3 $8.;
format weight weights1-weights3 best. ;
retain animals: weights:;
array animals[3];
array weights[3];

if _n_ = 1 then do;
    animals[1] = a;
    animals[2] = b;
    animals[3] = c;
end;
else if _n_ = 2 then do;
    weights[1] = input(a,best.);
    weights[2] = input(b,best.);
    weights[3] = input(c,best.);
end;

if last then do;
    do i=1 to 3;
        animal = animals[i];
        weight = weights[i];
        output;
    end;
end;
drop i animals: weights: a b c;
run;

Read the values into 2 arrays, converting the weights from strings into numbers. Use the _N_ variable to figure out which array to populate. At the end of the data set, output the values in the arrays.

0
votes

I wouldn't give this as an answer to a homework problem that I actually wanted to get a good grade on (because it's far too advanced, so it's obvious you asked for help); but the hash solution is almost certainly the most flexible and what I'd hope someone doing this in the real world would do (assuming there is a 'don't use proc transpose' real world reason, such as available resources). The problem is somewhat undefined, so this is only moderately fault-tolerant.

data have;
input a $ b $ c $;
datalines;
dog    cat   camel
9      7     2534 
;;;;
run;

data _null_;
set have end=eof;
array charvars _character_;
if _n_ = 1 then do;
    length animal $15 weight 8;
    declare hash h();
    h.defineKey('row');
    h.defineData('animal','weight');
    h.defineDone();
end;
animal=' ';
weight=.;
do row = 1 to dim(charvars);
  rc_f = h.find();
  if rc_f ne 0 then do;
    animal=charvars[row];
    rc_a = h.add();
    animal=' ';
  end;
  else if rc_f eq 0 then do;
    weight=input(charvars[row],best12.);
    rc_r = h.replace();
  end;
end;
if eof then rc_o = h.output(dataset:'want');
run;
0
votes

Do you always have just two rows or is that the no of columns and the rows are dynamic?

If you have a dynamic no of rows and columns, then the ideal way will be to use open function, get the no of columns to a macro variable. This will be the no of rows in your new dataset. Then take the no of rows in your original dataset which will be the no of columns in your new dataset. This must happen before the actual Transpose method. Post this you can read it in to an array and using the macro variables as the dimensions output the values in to the new dataset.

Having said all this, why would you want to re-invent the wheel when you already have the SAS provided ready made transpose function?