Conversion factor numerically in a data frame

I have coefficients from 0 to 39. Here's how they are ordered now:

> levels(items$label) [1] "0" "1" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" [13] "2" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "3" [25] "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "4" "5" [37] "6" "7" "8" "9" 

How to change their order in numerical order for display? I do not want to change the value of the data frame.

UPDATE: how to update the original data frame, items , with sorted coefficient, labels ? This should not significantly change the data structure; I just want the factors to come out in the correct order in subsequent operations.

+5
source share
3 answers
 sorted_labels <- paste(sort(as.integer(levels(items$label)))) 

gives:

  [1] "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" [13] "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" [25] "24" "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "35" [37] "36" "37" "38" "39" 

Or (as stated in fooobar.com/questions/1471976 / ... ):

 sorted_labels <- order(levels(items$label)) - 1 # order by itself is a 1-based vector # using `- 1` gives a 0-based vector 

In the updated question, this updates the data frame:

 items$label <- factor(items$label, levels = sorted_labels) 
+3
source

If all integers are present, you can simply use order :

  order(levels(items$label)) - 1 # where the minus 1 is for starting from 0 

If not all integers are present, then you should use as.numeric, as you have.

+2
source

If you are looking for a solution for tidyverse / forcats :

Data Generation:

 items <- data.frame(label = as.character(0:39),stringsAsFactors = FALSE) # if stringsAsFactors = TRUE (default), items$label must be converted to character before casting to integer! factor(items$label) #> [1] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #> [24] 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #> 40 Levels: 0 1 10 11 12 13 14 15 16 17 18 19 2 20 21 22 23 24 25 26 ... 9 

using fct_relevel

 library(forcats) fct_relevel(items$label,function(x){as.character(sort(as.integer(x)))}) #> [1] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #> [24] 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #> 40 Levels: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ... 39 

this also works with fct_reorder

 fct_reorder(items$label,as.integer(items$label)) #> [1] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #> [24] 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #> 40 Levels: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ... 39 

which opens up some good opportunities if your vector also contains a character (e.g. 1 egg , 2 eggs etc.):

 items$label2 <- paste(items$label,"eggs") factor(items$label2) #> [1] 0 eggs 1 eggs 2 eggs 3 eggs 4 eggs 5 eggs 6 eggs 7 eggs #> [9] 8 eggs 9 eggs 10 eggs 11 eggs 12 eggs 13 eggs 14 eggs 15 eggs #> [17] 16 eggs 17 eggs 18 eggs 19 eggs 20 eggs 21 eggs 22 eggs 23 eggs #> [25] 24 eggs 25 eggs 26 eggs 27 eggs 28 eggs 29 eggs 30 eggs 31 eggs #> [33] 32 eggs 33 eggs 34 eggs 35 eggs 36 eggs 37 eggs 38 eggs 39 eggs #> 40 Levels: 0 eggs 1 eggs 10 eggs 11 eggs 12 eggs 13 eggs ... 9 eggs library(readr) fct_reorder(items$label2,parse_number(items$label2)) #> [1] 0 eggs 1 eggs 2 eggs 3 eggs 4 eggs 5 eggs 6 eggs 7 eggs #> [9] 8 eggs 9 eggs 10 eggs 11 eggs 12 eggs 13 eggs 14 eggs 15 eggs #> [17] 16 eggs 17 eggs 18 eggs 19 eggs 20 eggs 21 eggs 22 eggs 23 eggs #> [25] 24 eggs 25 eggs 26 eggs 27 eggs 28 eggs 29 eggs 30 eggs 31 eggs #> [33] 32 eggs 33 eggs 34 eggs 35 eggs 36 eggs 37 eggs 38 eggs 39 eggs #> 40 Levels: 0 eggs 1 eggs 2 eggs 3 eggs 4 eggs 5 eggs 6 eggs ... 39 eggs 

Created on 2019-06-26 by the view package (v0.3.0)

All output from the fct_ * functions can be written back to the original. For instance:

 items$data <- fct_reorder(items$label,as.integer(items$label)) 
0
source

All Articles