Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R: Reorder levels of a factor alphabetically but one

Tags:

r

I would like to re-order the levels of a factor so the new order displays all the values alphabetically except one (Other) which I would like it to be the last one.

Let's imagine we have this factor:

x <- factor(c("Yes", "No", "Other", "Yes", "No", "Other"))

> x
[1] Yes   No    Other Yes   No    Other
Levels: No Other Yes

I would like their levels to be displayed in this order: "Yes", "No", "Other", instead of the default one. I know in this silly example I could easily achieve that by doing:

x2 <- factor(c("Yes", "No", "Other", "Yes", "No", "Other"), 
             levels = c("Yes", "No", "Other"))

Which would result in what I wanted:

> x2
[1] Yes   No    Other Yes   No    Other
Levels: Yes No Other

But that would not be so funny if we had a vector with several different levels and we don't want to write them again, after all their order is fine except for one!

Is there any better way to solve this without having to write the whole vector from scratch?

like image 369
ccamara Avatar asked Sep 10 '25 22:09

ccamara


2 Answers

You can now do this easily with forcats::fct_relevel

With your example:

> x <- factor(c("Yes", "No", "Other", "Yes", "No", "Other"))
> x
[1] Yes   No    Other Yes   No    Other
Levels: No Other Yes

# set "Yes" as first level and keep the rest alphabetically ordered
> x2 <- fct_relevel(x, "Yes")
> x2
[1] Yes   No    Other Yes   No    Other
Levels: Yes No Other
like image 199
Paul Campbell Avatar answered Sep 12 '25 23:09

Paul Campbell


You are going to have to explicitly specify the new levels= you want, but there are easier ways than typing them all to move them around. For example

x <- factor(c("Yes", "No", "Other", "Yes", "No", "Other"))
old.lvl<-levels(x)
x<-factor(x, levels=c(sort(old.lvl[old.lvl!="Other"], decreasing=T), "Other"))
x
# [1] Yes   No    Other Yes   No    Other
# Levels: Yes No Other

Of course this is a somewhat silly example, but there is no just "move-one" option for factor levels. You can take advantage of R's rich indexing operations to move them around however you like.

like image 34
MrFlick Avatar answered Sep 12 '25 23:09

MrFlick