turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- Base SAS Programming
- /
- How to use call sortn with a multidimensional arra...

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

10-26-2012 07:21 PM

In response to a post earlier today I used a slightly modified version of one of Paul Dorfman's old sort macros to do what I wanted, but I was wondering if one could accomplish the same result using call sortn. Yes, I know that the problem can be addressed with either a hash or proc surveyselect, but I'm more interested in knowing how to sort a multidimensional array based on just one of the dimensions.

In the present case I was trying to randomly assign values to 5 different groups over 10,000 iterations. e.g., I think the following does what I want to know if/how it could be done using call sortn using just one two-dimensional array:

%let n=1000;

%macro combsort (arr1 =, arr2=, order= <);

drop __:;

do __g = hbound (&arr1) - 1 by 0 while (__s or __g > 1);

__g = int (__g / 1.3);

if __g in (0 ) then __g = 1;

else if __g in (9, 10) then __g = 11;

__s = 0;

do __j = lbound (&arr1) to hbound (&arr1) - __g;

__k = __j + __g;

if &arr1[__j] &order &arr1[__k] then continue;

__t = &arr1[__j];

&arr1[__j] = &arr1[__k];

&arr1[__k] = __t;

__t = &arr2[__j];

&arr2[__j] = &arr2[__k];

&arr2[__k] = __t;

__s = 1;

end;

end;

%mend;

data want (keep=trial group;

array values(&n.);

do until (eof);

set hej end=eof;

i+1;

values(i)=y;

end;

array ordering(&n.);

array group1_(%eval(&n./5));

array group2_(%eval(&n./5));

array group3_(%eval(&n./5));

array group4_(%eval(&n./5));

array group5_(%eval(&n./5));

do trial=1 to 10000;

do i=1 to &n.;

ordering(i)=ranuni(0);

end;

%combsort(arr1=ordering, arr2=values);

k=0;

do i=1 to 5;

do j=1 to %eval(&n./5);

k+1;

if i eq 1 then group1_(j)=values(k);

else if i eq 2 then group2_(j)=values(k);

else if i eq 3 then group3_(j)=values(k);

else if i eq 4 then group4_(j)=values(k);

else if i eq 5 then group5_(j)=values(k);

end;

end;

output;

end;

run;

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to art297

10-29-2012 12:27 AM

Art.T

That is easy. Using macro variable to wrap these array elements.

If you know some algorithm about sorting, then you don't need function SORTN() either .

data _null_; length x $ 200; do i=1 to 2; do j=1 to 3; x=catx(',',x,cats('a{',i,',',j,'}')); end; call symputx(cats('a',i),x); call missing(x); end; run; %put _user_; data _null_; array a{2,3} _temporary_ (2 4 1 5 3 2 ) ; call sortn(&a1); call sortn(&a2); do i=1 to 2; do j=1 to 3; put a{i,j}= @; end; put / ; end; run;

Ksharp

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Ksharp

10-29-2012 09:17 AM

: Thanks for trying, but not quite what I was looking for. My example apparently wasn't sufficiently clear. Hopefully, the following example conveys the intent better:

Have:

19 97 40 26

92 96 54 53

05 07 82 52

Want Possiblity 1 (sorted by the bottom row's values):

19 97 26 40

92 96 53 54

05 07 52 82

Want Possiblity 2 (sorted by the right most column's values):

19 97 40 26

05 07 82 52

92 96 54 53

I know how to accomplish it with some macro code sorting related one-dimensional arrays, but was hoping sortn and sortc could handle it. Thus far, the calls don't appear to have that functionality.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to art297

10-29-2012 02:48 PM

Why not write it to a dataset and then use proc sort? Would easily handle the second example. To do the first just write it out by column instead of rows.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to art297

10-29-2012 11:19 PM

Arthur.T ,

Oh. I do not think call sortn() can do this. call sortn() is only used to process an simple observation(e.g a record) , not manipulate a whole vector .For your purpose, the RETAIN statement is more suited.

Possibility 1:

data _null_; array a{3,4} _temporary_ (19 97 40 26 92 96 54 53 05 07 82 52 ) ; if a{1,3} gt a{1,4} then do; temp=a{1,4}; a{1,4}=a{1,3}; a{1,3}=temp; temp=a{2,4}; a{2,4}=a{2,3}; a{2,3}=temp; temp=a{3,4}; a{3,4}=a{3,3}; a{3,3}=temp; end; do i=1 to 3; do j=1 to 4; put a{i,j} 3. @; end; put / ; end; run;

Possibility 2:

data _null_; array a{3,4} _temporary_ (19 97 40 26 92 96 54 53 05 07 82 52 ) ; do i=1 to 3; do j=i+1 to 3; if a{i,4} gt a{j,4} then do; temp=a{j,4}; a{j,4}=a{i,4}; a{i,4}=temp; temp=a{j,3}; a{j,3}=a{i,3}; a{i,3}=temp; temp=a{j,2}; a{j,2}=a{i,2}; a{i,2}=temp; temp=a{j,1}; a{j,1}=a{i,1}; a{i,1}=temp; end; end; end; do i=1 to 3; do j=1 to 4; put a{i,j} 3. @; end; put / ; end; run;

Ksharp

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Ksharp

10-29-2012 11:45 PM

Ksharp, not to pick on you. Although temporary array is automatically retained, but there is no 'retain statement' in either of your code like you suggested.

Haikuo

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Haikuo

10-30-2012 01:24 AM

Yeah. What I mean is what TOM mean, using a dataset hold these data and use RETAIN statement to reorder these variables . I think it would be easier and better for this case.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to art297

10-30-2012 09:14 AM

Thanks to Tom and Ksharp. I've marked this thread as 'assumed answered' as it appears that the answer is simply that call sortn and call sortc can't be used this way. I'm going to stick with Paul Dorfman's macro for separating multidimensional arrays into a set of one dimensional arrays, sort the desired dimension, and shift the other arrays during the sorting process.

That approach was the most suitable in the present case as the array had to be created and sorted, on the fly, separately for each record. Using retain, or re-writing the file and sorting it, added too many unnecessary complications.