使mixedsort区分大小写? [R]

时间:2013-09-02 11:47:34

标签: r sorting

我正在尝试按自然顺序对字符向量进行排序(因为人类会对其进行排序),但会考虑大小写差异。例如,在下面的向量中,我想独立地对所有小的“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执行类似的功能不起作用。

我有几个向量以这种方式排序,它们包含示例中未包含的字符,所以找到一般的方法很好。

想法?也许有一些明显的东西我不见了。感谢。

1 个答案:

答案 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))