Re-Ordering Factor Levels in Data Frame

Re-ordering factor levels in data frame

Assuming your dataframe is mydf:

mydf$task <- factor(mydf$task, levels = c("up", "down", "left", "right", "front", "back"))

Change factor levels and rearrange dataframe

This mistakes is easy to make. You have to supply the column vector to fct_relevel. Like so:


library(dplyr,warn.conflicts = F)
library(forcats)

df <-
structure(
list(layer = structure(
1:5,
.Label = c(
'CEOS and managers',
'Clerks and services',
'Production',
'Professionals',
'Technicians'
),
class = 'factor'
)),
row.names = c(NA,-5L),
class = c('tbl_df', 'tbl', 'data.frame')
)

df %>%
mutate(layer = forcats::fct_relevel(
layer,c(
'CEOS and managers',
'Professionals',
'Technicians',
'Clerks and services',
'Production'))) %>%
arrange(layer)
#> # A tibble: 5 x 1
#> layer
#> <fct>
#> 1 CEOS and managers
#> 2 Professionals
#> 3 Technicians
#> 4 Clerks and services
#> 5 Production

Created on 2021-01-11 by the reprex package (v0.3.0)

Reordering levels of a factor in R data.frame

We can specify the levels as the mixedsorted levels of the 'f' column.

 df$f <- factor(df$f, levels=mixedsort(levels(df$f), decreasing=TRUE))
levels(df$f)
#[1] "B-1" "B-2" "B-9" "B-10" "B-11"

Or as suggested by @Ben Bolker, a variation would be

 df <- transform(df,f=factor(f,levels=mixedsort(levels(f), 
decreasing=TRUE)))

and I guess - is interpreted as minus sign as @Gregor suggested in the comments.

How can I sort a dataframe by a predetermined order of factor levels in R?

We can specify the levels of the 'group' as category_order and that use that to `arrange

library(dplyr)
df1 <- df %>%
arrange(factor(group, levels = category_order))
df1
# group value
#1 tree 50
#2 house 2
#3 lake 1
#4 human 5

Or using fct_relevel

library(forcats)
df %>%
arrange(fct_relevel(group, category_order))

change factor levels to custom order of a column

Nothing wrong with the tidyverse/forcats solution, but the base-R solution is to use factor() with the levels argument specified in the desired order:

data$veh <- factor(data$veh, levels=c("car","cycle","bike"))

Contrary to common belief, ordered=TRUE isn't typically necessary in this case (even ordinary factors have an ordering), unless you specifically want to treat the focal variable as an ordinal variable (in which case R will use orthogonal polynomial contrasts, rather than treatment contrasts, by default), or want to be able to use comparison operators on the variable (e.g. veh > "car"); if you're not sure, the default (ordinary) factors are probably fine.

Reorder factor levels by pattern

You can create your desired factor levels programmatically.

lvls <- do.call(paste, c(tidyr::expand_grid(
c('Female', 'Male'), c('18_34', '35_49'), c('HS', 'CG')), sep = '-'))
lvls
#[1] "Female-18_34-HS" "Female-18_34-CG" "Female-35_49-HS" "Female-35_49-CG"
#[5] "Male-18_34-HS" "Male-18_34-CG" "Male-35_49-HS" "Male-35_49-CG"

You can use this lvls as levels in the factor call.

How can I arrange data.frame according to the factor levels?

Like this?

arrange(df, match(df$index, levels(df$index)))

index amount
1 a 76
2 b 10
3 e 60

Data

df<-data.frame(index=c("b","a","e"),amount=c(10,76,60))
df$index<-factor(df$index,levels=c("b","e","a"))

Reorder factor levels within group

To reorder the factor levels you can use forcats (part of the tidyverse), and do something like this...

library(forcats)
df2 <- df %>% mutate(a_factor = fct_reorder(a_factor,
value*(-1 + 2 * (group=="group1"))))

levels(df2$a_factor)
[1] "f" "e" "d" "a" "b" "c"

This does not rearrange the dataframe itself...

df2
a_factor group value
1 a group1 1
2 b group1 2
3 c group1 3
4 d group2 4
5 e group2 5
6 f group2 6

Reorder levels of a factor without changing order of values

Use the levels argument of factor:

df <- data.frame(f = 1:4, g = letters[1:4])
df
# f g
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d

levels(df$g)
# [1] "a" "b" "c" "d"

df$g <- factor(df$g, levels = letters[4:1])
# levels(df$g)
# [1] "d" "c" "b" "a"

df
# f g
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d


Related Topics



Leave a reply



Submit