anotherfred anotherfred - 7 months ago 56
R Question

Custom sort without using factor

I have a dataframe with a column named

. The dataframe is generated from a regularly updated excel file.

This column should only have a certain few values in it, such as 'Planning', or 'Analysis', but people occasionally put custom values in and it is impractical to stop.

I want the dataframe sorted by this column, with a custom sort order that makes sense chronologically (e.g for us, planning comes before analysis). I would be able to implement this using factors (e.g. Reorder rows using custom order ), but if I use a predefined list of factors, I lose any unexpected values that people enter into that column. I am happy for the unexpected values not to be sorted properly but I don't want to lose them entirely.

EDIT: Answer by floo0 is amazing, but I neglected to mention that I was planning on barplotting the results, something like

barplot(table(MESH_assurance_involved()[MESH_assurance_invol‌​ved_sort_order(), 'Stage']), main="Stage became involved")

(parentheses because these are shiny reactive objects, shouldn't make a difference).

The results are unsorted, although testing in the console reveals the underlying data is sorted.

is also breaking the sorting but using
and no table I get the identical result.

To display a barplot maintaining the source order seems to require something like Ordering bars in barplot() but all solutions I have found require factors, and mixing them with the solution here is not working for me somehow.


Toy data-set:

dat <- data.frame(Stage = c('random1', 'Planning', 'Analysis', 'random2'), id=1:4,
                  stringsAsFactors = FALSE)

So dat looks as follows:

> dat
     Stage id
1  random1  1
2 Planning  2
3 Analysis  3
4  random2  4

Now you can do something like this:

known_levels <- c('Planning', 'Analysis')
my_order <- order(factor(dat$Stage, levels = known_levels, ordered=TRUE))
dat[my_order, ]

Which gives you

     Stage id
2 Planning  2
3 Analysis  3
1  random1  1
4  random2  4