data testy;
input a;
datalines;
1
2
3
4
5
6
7
8
9
;
run;
/*how to swap first obs and last obs each other in SAS*/
required output
9
2
3
4
5
6
7
8
1
Question: How to swap values each other as above required output
Interesting task.
Maybe something like:
data _null_;
call symputx('lastObs', _nobs);
call symputx('beforeLast', _nobs -1);
if 0 then set work.have nobs=_nobs;
run;
data want;
set
work.have(firstobs=&lastObs.)
work.have(firstobs=2 obs=&beforeLast.)
work.have(firstobs=1 obs=1)
;
run;
If you want to swap two specific rows, like the ith and the jth row, obs= and firstobs= options would be very efficiently.
data want;
set testy(firstobs=9 obs=9) testy(firstobs=2 obs=8) testy(firstobs=1 obs=1);
run;
If you want to swap two variant rows, like the first and last row, or some rows which be determined by a variable, you may need direct access method.
data want;
set testy nobs=nobs end=eof;
if _n_=1 then set testy point=nobs;
if eof then set testy point=eof;
run;
Hi Whymath
Thank you for your solution
supposer we want swap range of values how to achieve
example required output
9
8
7
4
5
6
3
2
1
You can try something like this for the last wanted result you show:
data want;
do _N_=nobs to nobs-2 by -1, 4 to nobs-3, 3 to 1 by -1;
set have point=_N_ nobs=nobs;
output;
end;
stop;
run;
Your original result with the same style of coding:
data want;
do _N_=nobs, 2 to nobs-1, 1;
set have point=_N_ nobs=nobs;
output;
end;
stop;
run;
@pavank wrote:
Hi Whymath
Thank you for your solution
supposer we want swap range of values how to achieve
example required output
9
8
7
4
5
6
3
2
1
You can (edited response):
data have;
do i=1 to 9; output; end;
run;
%let groupsize_beg=3;
%let groupsize_end=3;
data want;
do ptr= n_last to n_last +1 -&groupsize_end by -1
, &groupsize_beg+1 to n_last-&groupsize_end
, &groupsize_beg to 1 by -1;
set have point=ptr nobs=n_last;
output;
end;
stop;
run;
or you can make it more compact via:
data want;
ptr=ifn(_n_=1,n_last,ptr-1);
if ptr=0 then stop;
/*Read end group and begin group in reverse order, using "POINT=" */
if _n_<=&groupsize_end or _n_> n_last-&groupsize_beg then set have point=ptr nobs=n_last;
/*Otherwise read middle group in original order */
else set have (firstobs=%eval(&groupsize_beg+1));
run;
The below is stricken out, once I realized you want the last batch of records in reverse order.
data have; do i=1 to 9; output; end; run; %let groupsize_beg=3; %let groupsize_end=3; data want; do ptr= n_last to n_last +1 -&groupsize_end by -1 , &groupsize_beg+1 to n_last-&groupsize_end , 1 to &groupsize_beg; set have point=ptr nobs=n_last; output; end; stop; run;
or slightly more compact, No STOP statement is required because the second and third SETs do not use the POINT= option:
data want; ptr = n_last + 1 - _n_; if _n_<=&groupsize_end then set have point=ptr nobs=n_last; else if _n_<= n_last-&groupsize_beg then set have (firstobs=%eval(&groupsize_beg+1)); else set have (obs=&groupsize_beg); run;
Let us broaden the question a bit. WHY exactly is the order of values of a single variable important? As in, what impact does it have on analysis or reporting?
An abstract example like this is quite often amenable to a solution but then when you try to expand its use, such as to groups of values within an analysis group, think geographic region or demographic group, it becomes quite complex. But may not actually be needed depending on your actual use need.
data want;
if _n_=1 then set have nobs=n_last point=n_last;
else set have (firstobs=2) end=end_of_have;
if end_of_have then set have (obs=1);
run;
data want; if _n_=1 then set sashelp.class nobs=n_last point=n_last; else set sashelp.class (firstobs=2) sashelp.class (obs=1); run;
You could consider a format to create a grouping for values. Many SAS Procs can return results ordered by formatted values without the need to pre-sort the input data.
data have;
input row_id;
datalines;
1
2
3
4
5
6
7
8
9
;
proc format;
value ValGroup
7-9 = 1
1-6 = 2
other = 3
;
run;
proc sql;
/* create table want as*/
select row_id
from have
order by put(row_id,ValGroup.), row_id
;
quit;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.