How to Set Factor Levels to the Order They Appear in a Data Frame

How do I set factor levels to the order they appear in a data frame?

One way around this is to change your ggplot call to

ggplot(df, aes(variable, factor(school, levels = unique(school)))) + ...

To avoid typing this every time, you can create a function

f <- function(x) factor(x, levels = unique(x))

and then call it by ggplot(df, aes(variable, f(school))) + ...

Note that this will place the first level of the factor at the bottom of the plot. If you want it at the top, you need to change f to function(x) factor(x, levels = rev(unique(x)))

How to set factor levels order according to appearance of values in another column?

As you provided poor reproducible data I will use my own:

d <- structure(list(label = c(1L, 1L, 1L, 2L, 2L, 1L, 2L, 1L, 2L, 
2L), digit = c(9L, 9L, 6L, 9L, 9L, 0L, 4L, 4L, 4L, 4L), timediff = c(0L,
9L, 17L, 17L, 8L, 8L, 200L, 17L, 17L, 8L)), .Names = c("label",
"digit", "timediff"), class = "data.frame", row.names = c(NA,
-10L))

Then you can try a tidyverse

d %>% 
mutate(digit=factor(digit, levels = c(9,4,6,0))) %>%
arrange(label, digit)
label digit timediff
1 1 9 0
2 1 9 9
3 1 4 17
4 1 6 17
5 1 0 8
6 2 9 17
7 2 9 8
8 2 4 200
9 2 4 17
10 2 4 8

Then for the interaction use:

d %>% 
mutate(digit=factor(digit, levels = c(9,4,6,0))) %>%
arrange(label, digit) %>%
unite(ID, label, digit, sep=".") %>%
mutate(ID=factor(ID, levels = unique(ID))) %>%
with(.,levels(ID))
[1] "1.9" "1.4" "1.6" "1.0" "2.9" "2.4"

Or in base R simply use order

d[order(d$label, factor(d$digit,levels = c(9,4,6,0))),]
label digit timediff
1 1 9 0
2 1 9 9
8 1 4 17
3 1 6 17
6 1 0 8
4 2 9 17
5 2 9 8
7 2 4 200
9 2 4 17
10 2 4 8

Then

d1 <- d[order(d$label, factor(d$digit,levels = c(9,4,6,0))),]
d1$combined_factor <- with(d1, interaction(label, digit))
d1$combined_factor <- factor(d1$combined_factor, levels = unique(d1$combined_factor))
levels(d1$combined_factor)
[1] "1.9" "1.4" "1.6" "1.0" "2.9" "2.4"

As ya function you can try

foo <- function(df, Code) df[order(df$label, factor(df$digit, levels = Code)),]
foo(d, c(9,4,6,0))

There is no need to work with the interaction part. If you need it. creat the interaction afterwards using 1) tidyr's unite or 2) interaction. See also ?sort: "The sort order for factors is the order of their levels". Thus you simply have to change the factor levels.

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.

How to order the levels of factors according to the ordering of a data.frame (and not alphabetically)

This should be a general solution:

> factor(dd$x, as.character(unique(dd$x)))
[1] A D A C
Levels: A D C

Again, however, your example data do not seem to conform with what you describe as the intended result.

I guess you might also want:

> factor(dd$x, rev(as.character(unique(dd$x))))
[1] A D A C
Levels: C D A

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"))

Changing order of factor levels based on lookup in other column

Try this:

factor(df$val, levels = unique(df$val[order(df$id)]))

Sorting the values inside row in a data frame, by the order of its factor levels?

In your code, the issue is happening at this line.

arcana_table <- as.data.frame(matrix(shuffled_arcana, nrow = 5, ncol = 5))

shuffled_arcana is a factored vector but you cannot have a factor-matrix so it changes the vector from factor to character and hence, sorting does not happen as desired.

Here's a way -

set.seed(2022)

arcanaVector <- c(rep("Supreme", 3),
rep(c("Good", "Moderate", "Poor", "Awful"), each = 5),
rep("Worst", 2))
arcanaLevels <- c("Supreme", "Good", "Moderate", "Poor", "Awful", "Worst")
shuffled_arcana <- sample(arcanaVector)
arcana_table <- matrix(shuffled_arcana,nrow = 5, ncol = 5)
row.names(arcana_table) <- c("Presence", "Manner", "Expression", "Complexity", "Tradition")

arcana_table <- apply(arcana_table, 1, function(x) sort(factor(x, arcanaLevels))) |>
t() |>
as.data.frame()

arcana_table

# V1 V2 V3 V4 V5
#Presence Good Good Good Good Awful
#Manner Supreme Moderate Poor Awful Awful
#Expression Supreme Supreme Moderate Moderate Poor
#Complexity Moderate Moderate Poor Poor Worst
#Tradition Good Poor Awful Awful Worst

If you want to change a specific row you may use -

arcana_table[1, ] <- as.character(sort(factor(arcana_table[1, ], arcanaLevels))) 

Order factor levels in order of appearance in data set

I think the data.table way to do this will be

dt[, idx := .GRP, by = question]

## question value idx
## 1: C 10 1
## 2: C 20 1
## 3: A 30 2
## 4: B 40 3
## 5: B 20 3
## 6: D 30 4

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"))


Related Topics



Leave a reply



Submit