You are here:
Vanderbilt Biostatistics Wiki
>
Main Web
>
Seminars
>
RClinic
>
MultiSortFunction
(revision 1) (raw view)
Edit
Attach
<highlight> # this first multisort was the original way I wrote it # it could have a maximum of four columns to sort # multisort<-function(frame, col1, dec1=F, col2, dec2=F, col3="", dec3=F, col4="", dec4=F){ # #there are three required arguments, frame, col1, and col2 # #this means you must have at least two columns from a dataset that you want to sort # if(col4=="") { # if(col3=="") { # #only have two columns to sort # sub<-frame[order(getVal(frame,col2),decreasing=dec2),] # } else { # #three columns to sort # sub<-multisort(frame,col2,dec2,col3,dec3) # } # } else { # #must sort all four columns # if(col3=="") { # #quit trying to mess up the function # sub<-multisort(frame,col2,dec2,col4,dec4) # } # sub<-multisort(frame,col2,dec2,col3,dec3,col4,dec4) # } # sub[order(getVal(sub,col1),decreasing=dec1),] # } #to sort just numeric values #x[order(x$SAL,-x$AB),] tmp<-read.csv('kforce.csv', header=T) multisort<-function(frame, col1, dec1, col2, dec2, ...) { #before doing any sorting, convert arguments into two vectors mylist<-list(...) col<-as.vector(c(col1,col2)) dec<-as.vector(c(dec1,dec2)) count<-6 for(i in mylist) { if(i==TRUE || i==FALSE) { if(count%%2==1) { dec[count%/%2]<-i count<-count+1 } } else { if(count%%2==0) { count<-count+1 } else { count<-count+2 } #set vectors, default dec to FALSE col[count%/%2]<-i dec[count%/%2]<-F } } #the function parameters must be valid now if(length(col)>2) { extraArgs<-vector() count<-1 for(i in col) { pos=(count+1)%/%2 if(count>5) { #append value to extraArgs extraArgs[count-6]<-col[pos] extraArgs[count-5]<-dec[pos] } count<-count+2 } if(length(col)==3) { sub<-multisort(frame,col[2],dec[2],col[3],dec[3]) } else { sub<-multisort(frame,col[2],dec[2],col[3],dec[3],extraArgs) } } else { #only two columns to sort - this is where the recursion ends! sub<-frame[order(getVal(frame,col2),decreasing=dec2),] } sub[order(getVal(sub,col1),decreasing=dec1),] } getVal<-function(frame,col) { eval(parse(text=paste(quote(frame),col,sep="$"))) } multisort(tmp,"CO",T,"SAL",F,"POS",T,"AB") #there are a few rules to make sure this works #you must set descending to T or F for the first two columns (3rd & 5th argument) #don't set arguments equal to a variable name (except for the first 5 arguments) #the 6th argument (assuming it's a legitimate column) will be set to col3 regardless if set to something in function call </highlight> * Another solution from Tatsuki Koyama -- much shorter R code which probably does the same thing: <highlight> sort.mat3 <- function(mat, sort.by, decreasing = F){ # This will sort a matrix or a data.frame based on the columns 'sort.by.' # 'sort.by' and 'decreasing' are vectors of any length with length(sort.by) >= length(decreasing). v <- rev(sort.by) ; de <- decreasing if( length(de) < length(v) ){de[(length(de)+1) : length(v)] <- F} for(i in 1:length(v)){ mat <- mat[order(mat[,v[i]], decreasing=rev(de)[i]),]} mat} # To reproduce Cole's example, # > multisort(tmp,"CO",T,"SAL",F,"POS",T,"AB") # do sort.mat3(tmp, c(6,5,3), c(T, F, T)) # because "CO" is the 6th column, "SAL" is 5th and "POS" is 3rd column. </highlight>
Edit
|
Attach
|
P
rint version
|
H
istory
:
r2
<
r1
|
B
acklinks
|
V
iew topic
|
Edit WikiText
|
More topic actions...
Topic revision: r1 - 08 Nov 2006,
TheresaScott
Main
Department Home Page
Biostatistics Graduate Program
Vanderbilt University Medical Center
Main Web
Main Web Home
Search
Recent Changes
Changes
Topic list
Biostatistics Webs
Archive
Main
Sandbox
System
Register
|
Log In
Copyright © 2013-2022 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Vanderbilt Biostatistics Wiki?
Send feedback