3

im having some trouble figuring out how to do this.

I want to sort a dataframe by a column containing factors that are the same as the factors I have in a list. It is important that the code doesn't change the order of the rows in each factor though.

Ideas?

edit:

salmon <- c("red", 3,7, 5)
bass <- c("red", 1,3,5)
shrimp <- c("blue", 1, 4, 2)
carp <- c("orange", 6, 6, 6)

dfex <- data.frame(salmon, bass, shrimp, carp)
dfex <- data.frame(t(dfex))

ordering <- c("blue", "orange", "red")

so the idea here is to reorder the dataframe by using the ordering vector

user2795569
  • 343
  • 2
  • 9
  • 2
    [Reproducible example?](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – Jilber Urbina Oct 08 '13 at 12:41
  • 1
    Yes, I did down-vote. You were asked for exactly the same in your previous question - to provide a reproducible example. – Henrik Oct 08 '13 at 12:46
  • 1
    dont downvote unless you are going to come back and get rid of downvote when I fix the problem............. – user2795569 Oct 08 '13 at 12:59
  • 1
    Usually you just get down vote and you're scr... – alap Oct 08 '13 at 13:06
  • 1
    @user2795569, you might want to ping the person you're responding to if you want to get their attention. They may not be watching your question to see whether you've bothered to make an edit or not. – A5C1D2H2I1M1N2O1R2T1 Oct 08 '13 at 13:36

2 Answers2

12

A combination of match() and order() should do it.

dfex[order(match(dfex[[1]], ordering)), ]

match() will tell you the index position of each value in the first column as found in ordering. And sorting by these positions will result in an order that matches the order of ordering.

Ciarán Tobin
  • 7,306
  • 1
  • 29
  • 45
6

First, the way you build your data frame is a bit complicated. You can do something like the following instead :

dfex <- data.frame(v1=c("salmon","shrimp","carp"),
                   v2=c("red","blue","orange"),
                   v3=c(3,1,6),
                   v4=c(7,4,6),
                   v5=c(5,2,6))

Then you can order your data frame by using row names :

order <- c("blue", "orange", "red")
rownames(dfex) <- dfex$v2
dfex[order,]     

Which gives :

           v1     v2 v3 v4 v5
blue   shrimp   blue  1  4  2
orange   carp orange  6  6  6
red    salmon    red  3  7  5
juba
  • 47,631
  • 14
  • 113
  • 118
  • Does this work if we have multiples of factor, as in my edited example? I cant get it to work on my end. – user2795569 Oct 08 '13 at 13:12
  • 1
    @juba I'm not sure how you can make this work if you add the `bass` to the data.frame (that creates duplicate rowname using your method). – plannapus Oct 08 '13 at 13:12
  • @juba i would suggest making a factor out of v2 with the order desired as levels (`dfex$v2<-factor(dfex$v2,levels=order)`) and then order using `dfex[order(dfex$v2),]`. – plannapus Oct 08 '13 at 13:15
  • @plannapus is right, it won't work if you don't have unique values in your ordering column. – juba Oct 08 '13 at 13:16