2
votes

I have a data frame which looks like this:

structure(list(Mash_pear = c(0.192474082559755, 0.679726904159742, 
0.778564545349054, 0.573745352397321, 0.56633658385284, 0.472559997318901, 
0.462635414367878, 0.562128414492567, 0.354624921832056, 0.64532681437697
), tRap_pear = c(0.0350096175177328, 0.234255507711743, 0.23714999195134, 
0.185536020521134, 0.191585098617356, 0.201402054387186, 0.220911538536031, 
0.216072802572045, 0.132247101763063, 0.172753098431029), Beeml_pear = c(0.179209909971615, 
0.79129167285928, 0.856908302056589, 0.729078080521886, 0.709346164378725, 
0.669599784720647, 0.585348196746785, 0.639355942917055, 0.544909349368496, 
0.794652394149651), Mash_pear2080 = c(0.823944540480775, 0.816630852343513, 
0.81134728399675, 0.801065036203532, 0.799630945085954, 0.799195606444727, 
0.798637867344115, 0.798478922129054, 0.798090734787886, 0.797673368802285
)), .Names = c("Mash_pear", "tRap_pear", "Beeml_pear", "Mash_pear2080"
), row.names = c("Aft1", "Alx3_3418.2", "Alx4_1744.1", "Arid3a_3875.1_v1_primary", 
"Arid3a_3875.1_v2_primary", "Arid3a_3875.2_v1_primary", "Arid3a_3875.2_v2_primary", 
"Arid5a_3770.2_v1_primary", "Arid5a_3770.2_v2_primary", "Aro80"
), class = "data.frame")

Now i had the idea to rank those scores, but every columns should be ranked separately with keeping the row names intact. So i tried to extract all the columns 1 by 1 and order them. The problem i'm experiencing is occurring when trying to order 1 column. Namely my dataframe disappears and becomes a vector of numeric values and as i already pointed out, i need the data frame (rownames) to stay as is, only ordered. The code i'm working on right now is here:

rowname<-rownames(pearframe)
col1<-subset(pearframe, select=1)[order(pearframe),]
col2<-subset(pearframe, select=2)[order(pearframe),]
col3<-subset(pearframe, select=3)[order(pearframe),]
col4<-subset(pearframe, select=4)[order(pearframe),]

THIS removes my rownames and orginal data frame structure. Which makes it impossible to rank my data. So the actual question would be: How can i order/sort a data frame per column and create 4 new frames with 1 ordered column each. Eventually i want to have a table which exists of the rownames of every ranked frame and the scores.

2
what is your expected output?Nishanth
4 data frames with 1 column. So every columns should become a new data frame which has 1 columns of numeric values and the rownames of the old data frameSander Van der Zeeuw
What exactly do you want the final result to be? The table you describe at the end, that is?Thomas
The table at the end. Is constructed out of the 4 dataframes created before that so that i have a ranking per method. 1 Method is 1 column like MASH, tRAP and BEEML in the old frame the new frame should give me the rownames per method and ranked score of 1 method.Sander Van der Zeeuw

2 Answers

4
votes

Another way would be to take advantage of the fact that a data.frame is just a bunch of lists. You can use lapply and this will give you a list of data.frames. You can access each one by the column name and assign it to a new df if you wish:

ranks <- lapply( df , function(x) data.frame( rank = rownames(df)[ order( x ) ] , score = x[ order(x) ] ) )
names(ranks) <- names(df)

head(ranks[["Mash_pear"]])
#                     rank     score
#1                     Aft1 0.1924741
#2 Arid5a_3770.2_v2_primary 0.3546249
#3 Arid3a_3875.2_v2_primary 0.4626354
#4 Arid3a_3875.2_v1_primary 0.4725600
#5 Arid5a_3770.2_v1_primary 0.5621284
#6 Arid3a_3875.1_v2_primary 0.5663366

head(ranks[["tRap_pear"]])
#                     rank      score
#1                     Aft1 0.03500962
#2 Arid5a_3770.2_v2_primary 0.13224710
#3                    Aro80 0.17275310
#4 Arid3a_3875.1_v1_primary 0.18553602
#5 Arid3a_3875.1_v2_primary 0.19158510
#6 Arid3a_3875.2_v1_primary 0.20140205
4
votes

You'll need to use drop=FALSE twice, I think:

subset(pearframe, select=1,drop=FALSE)[order(pearframe[,1]),,drop=FALSE]

The other cases look the same, incrementing 1 both places it appears.

EDIT: Also, this is more concise:

pearframe[order(pearframe[,1]),1,drop=FALSE]

EDIT2: And this is how to make your final data.frame with this approach:

col_list <- list()
for (i in 1:4){
    col_list[[i]] <- pearframe[order(pearframe[,i]),i,drop=FALSE]
    col_rnname <- paste(names(pearframe)[[i]],"rn",sep=".")
    col_list[[i]][[col_rnname]] <- rownames(col_list[[i]])
    rownames(col_list[[i]]) <- NULL
}
col_mat <- do.call(cbind,col_list)