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.
| t | x1 | x4 | x3 | x2 | x5 |
| 1 | -0.43 | -2.28 | |||
| 2 | 1.45 | 1.8 | -1.79 | ||
| 3 | 0.78 | 1.45 | 0.62 | 0.43 | -0.92 |
| 4 | -1.19 | 0.66 | -0.76 | -0.84 | |
| 5 | 1.13 | -0.96 | 0.08 | -0.11 | |
| 6 | 0.59 | 0.29 | 0.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;
%longIs there a better solution?
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.
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)
Thanks, but cannot transpose pretrans because unsorted—but can understand the approach (appending template first as nametags).
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.
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;
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
Still thinking about your presentation idea? The submission deadline has been extended to Friday, Nov. 14, at 11:59 p.m. ET.
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.
Ready to level-up your skills? Choose your own adventure.