Hi everybody I am trying to solve a problem in R. I want to read a lot of files allocated in multiples sub folders in a main folder. Then I used list.files()
t
gtools::mixedsort
is designed for this...
gtools::mixedsort( c("A1","A10","A11","A12","A13","A14","A15","A2","A3","A4","A5","A6","A7") )
[1] "A1" "A2" "A3" "A4" "A5" "A6" "A7" "A10" "A11" "A12" "A13" "A14" "A15"
Thanks to @Matthew for the data
Rather than focussing on a particular example I suggest using an existing tool, mixedsort
in the gtools package that handles irregular widths of both the alpha and numeric characters.
require(gtools)
vec <- paste0( replicate(40, {
paste( sample(LETTERS, 3, repl=TRUE),collapse="")}),
sample(1:400, 40, repl=TRUE) )
mixedsort(vec)
[1] "ABP256" "ATV361" "ATZ12" "BKL273" "BOY273" "BQJ242" "CQL129"
[8] "CXH313" "CXQ249" "DFU116" "FGI305" "HJK249" "ICN4" "IML75"
[15] "JDJ309" "JEB93" "JHF276" "JIY265" "JXK287" "KCQ282" "MAR161"
[22] "MGV185" "MHH72" "NDJ84" "NGZ84" "OIV207" "ORK31" "PSJ95"
[29] "QOC178" "QXL344" "QYK285" "RFO98" "ROC135" "TUL40" "UBT134"
[36] "UKP14" "VQL372" "YLG393" "ZLD394" "ZSG180"
If mixedsort
didn't exist man would need to invent it. This is not exactly going to produce the same results but it might light a path forward:
vec[ order( gsub("[[:digit:]]", "", vec), gsub("[[:alpha:]]", "", vec) )]
[1] "ABP256" "ATV361" "ATZ12" "BKL273" "BOY273" "BQJ242" "CQL129"
[8] "CXH313" "CXQ249" "DFU116" "FGI305" "HJK249" "ICN4" "IML75"
[15] "JDJ309" "JEB93" "JHF276" "JIY265" "JXK287" "KCQ282" "MAR161"
[22] "MGV185" "MHH72" "NDJ84" "NGZ84" "OIV207" "ORK31" "PSJ95"
[29] "QOC178" "QXL344" "QYK285" "RFO98" "ROC135" "TUL40" "UBT134"
[36] "UKP14" "VQL372" "YLG393" "ZLD394" "ZSG180"
It collapse all the alpha characters together before the numerics and would order
"a12b" before "a99z".
There are a few ways to do this. Here's another one:
b <- c("A1","A10","A11","A12","A13","A14","A15","A2","A3","A4","A5","A6","A7")
b[order(nchar(b), b)]
# [1] "A1" "A2" "A3" "A4" "A5" "A6" "A7" "A10" "A11" "A12" "A13" "A14" "A15"
If this is the exact data that you have, you can sort it the way you want like this:
> b[order(as.integer(substr(b,2,3)))]
[1] "A1" "A2" "A3" "A4" "A5" "A6" "A7" "A8" "A9" "A10" "A11" "A12"
[13] "A13" "A14" "A15"
If the actual data is more complicated, you might have to do a little more string manipulation, but this is the general idea.