BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Junyong
Pyrite | Level 9

I want to transpose the following data set—the following is the working example, but the real data set has more than five is (and the is are non-continuous).

data have;
	input i t x;
cards;
1 1 -0.43
1 2 1.45
1 3 0.78
2 3 0.43
2 4 -0.76
2 5 0.08
2 6 0.31
2 7 -1.39
3 2 -1.79
3 3 0.62
3 4 0.66
3 5 -0.96
3 6 0.29
3 7 -2.13
3 8 -0.58
3 9 -2.59
3 10 -0.34
3 11 -0.17
3 12 -0.66
4 1 -2.28
4 2 1.8
4 3 1.45
4 4 -1.19
4 5 1.13
4 6 0.59
4 7 -0.67
5 3 -0.92
5 4 -0.84
5 5 -0.11
5 6 -1.47
;

The easiest way may be sort and then transpose as follows.

proc sort out=now;
	by t i;
run;

proc transpose prefix=x out=now(drop=_name_);
	by t;
	id i;
run;

The problem is the resultant variable order—transpose locates x4 first because x2 and x3 have no observation at t=1.

tx1x4x3x2x5
1-0.43-2.28   
21.451.8-1.79  
30.781.450.620.43-0.92
4 -1.190.66-0.76-0.84
5 1.13-0.960.08-0.11
6 0.590.290.31-1.47
7 -0.67-2.13-1.39 
8  -0.58  
9  -2.59  
10  -0.34  
11  -0.17  
12  -0.66  

The following code orderly locates all the is but will be inconvenient if there are too many is I need to code.

data want(drop=i);
	merge have(where=(i=1) rename=(x=x1))
		have(where=(i=2) rename=(x=x2))
		have(where=(i=3) rename=(x=x3))
		have(where=(i=4) rename=(x=x4))
		have(where=(i=5) rename=(x=x5));
	by t;
run;

Or I can use longer %macro as follows, but this version will be inaccurate as well if the macro variable list exceeds 65,534 characters.

%macro long;

proc sql noprint;
	select distinct i into :i separated by " " from have;
quit;

data long(drop=i);
	merge%do j=1 %to %sysfunc(countw(&i)); have(where=(i=%scan(&i,&j)) rename=(x=x%scan(&i,&j)))%end;;
	by t;
run;

%mend;

%long

Is there a better solution?

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

We need to incorporate the sort into the process:

data have;
input i t x;
cards;
1 1 -0.43
1 2 1.45
1 3 0.78
2 3 0.43
2 4 -0.76
2 5 0.08
2 6 0.31
2 7 -1.39
3 2 -1.79
3 3 0.62
3 4 0.66
3 5 -0.96
3 6 0.29
3 7 -2.13
3 8 -0.58
3 9 -2.59
3 10 -0.34
3 11 -0.17
3 12 -0.66
4 1 -2.28
4 2 1.8
4 3 1.45
4 4 -1.19
4 5 1.13
4 6 0.59
4 7 -0.67
5 3 -0.92
5 4 -0.84
5 5 -0.11
5 6 -1.47
;

proc sort
  data=have
;
by t i;
run;

proc sort
  data=have (keep=i)
  out=template
  nodupkey
;
by i;
run;

data pretrans/view=pretrans;
set
  template
  have
;
run;

proc transpose
  data=pretrans
  prefix=x
  out=want (drop=_name_ where=(t ne .))
;
by t;
id i;
run;

Code is now tested.

View solution in original post

4 REPLIES 4
Kurt_Bremser
Super User

Do this

proc sort
  data=have (keep=i)
  out=template
  nodupkey
;
by i;
run;

data pretrans/view=pretrans;
set
  template
  have
;
run;

proc transpose
  data=pretrans
  prefix=x
  out=now (drop=_name_ where=(t ne .))
;
by t;
id i;
run;

(untested, posted from my tablet)

Junyong
Pyrite | Level 9

Thanks, but cannot transpose pretrans because unsorted—but can understand the approach (appending template first as nametags).

Kurt_Bremser
Super User

We need to incorporate the sort into the process:

data have;
input i t x;
cards;
1 1 -0.43
1 2 1.45
1 3 0.78
2 3 0.43
2 4 -0.76
2 5 0.08
2 6 0.31
2 7 -1.39
3 2 -1.79
3 3 0.62
3 4 0.66
3 5 -0.96
3 6 0.29
3 7 -2.13
3 8 -0.58
3 9 -2.59
3 10 -0.34
3 11 -0.17
3 12 -0.66
4 1 -2.28
4 2 1.8
4 3 1.45
4 4 -1.19
4 5 1.13
4 6 0.59
4 7 -0.67
5 3 -0.92
5 4 -0.84
5 5 -0.11
5 6 -1.47
;

proc sort
  data=have
;
by t i;
run;

proc sort
  data=have (keep=i)
  out=template
  nodupkey
;
by i;
run;

data pretrans/view=pretrans;
set
  template
  have
;
run;

proc transpose
  data=pretrans
  prefix=x
  out=want (drop=_name_ where=(t ne .))
;
by t;
id i;
run;

Code is now tested.

ballardw
Super User

Do you actually need a data set?

If so, what are you doing that is column order dependent? SAS data sets and procedures really don't care about column order for a vast majority of processes.

 

If you need a report, that is something people read and get picky about column order maybe:

proc report data=have;
   column t i,x;
   define t /group;
   define i/across;
run;
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 1194 views
  • 0 likes
  • 3 in conversation