我正在尝试按自然顺序对字符向量进行排序(因为人类会对其进行排序),但会考虑大小写差异。例如,在下面的向量中,我想独立地对所有小的“m”和大的“M”进行排序。
x<- c("m10", "M10", "m11", "m12", "m2", "M2", "m3", "M3", "m4", "M4", "yo1", "yo2")
所以它看起来像:
DesiredSort(x)
[1] "M2" "M3" "M4" "M10" "m2" "m3" "m4" "m10" "m11" "m12" "yo1" "yo2"
从here开始,我了解如何将sort
考虑在内:
sortC <- function(...) {
a <- Sys.getlocale("LC_COLLATE")
on.exit(Sys.setlocale("LC_COLLATE", a))
Sys.setlocale("LC_COLLATE", "C")
sort(...)
}
sortC(x)
[1] "M10" "M2" "M3" "M4" "m10" "m11" "m12" "m2" "m3" "m4" "yo1" "yo2"
但这并没有给出自然的顺序。我知道gtools中的mixedsort
会在m10之前正确放置m2,所以:
mixedsort(x)
[1] "m2" "M2" "m3" "M3" "m4" "M4" "m10" "M10" "m11" "m12" "yo1" "yo2"
但是mixedsort
特别忽略了字符串的情况,因此对SortC执行类似的功能不起作用。
我有几个向量以这种方式排序,它们包含示例中未包含的字符,所以找到一般的方法很好。
想法?也许有一些明显的东西我不见了。感谢。
答案 0 :(得分:3)
您需要解决方案的一般性如何?下面的自定义解决方案适合您的数据集,但在包含任意字符串的向量的一般情况下,您想要发生的事情并不完全清楚(<至少对我而言)。
DesiredSort <- function(x)
{
library(stringr)
locale <- Sys.getlocale("LC_COLLATE")
on.exit(Sys.setlocale("LC_COLLATE", locale))
Sys.setlocale("LC_COLLATE", "C")
x_matches <- str_match(x, "(^[[:alpha:]]+)([[:digit:]]+)")[, 2:3]
x_data <- data.frame(
letter = x_matches[, 1],
number = as.numeric(x_matches[, 2])
)
o <- with(x_data, order(letter, number))
x[o]
}
x <- c("m10", "M10", "m11", "m12", "m2", "M2", "m3", "M3", "m4", "M4", "yo1", "yo2")
expected <- c("M2", "M3", "M4", "M10", "m2", "m3", "m4", "m10", "m11", "m12", "yo1", "yo2")
stopifnot(identical(DesiredSort(x), expected))