3

我正在尝试以自然顺序对字符向量进行排序(就像人类对其进行排序一样),但要考虑大小写差异。例如,在下面的向量中,我想对所有小“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"

这里我得到了如何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"

但这并没有给出自然的顺序。我mixedsort从 gtools 知道会正确地将 m2 放在 m10 之前,这样:

mixedsort(x)

[1] "m2"  "M2"  "m3"  "M3"  "m4"  "M4"  "m10" "M10" "m11" "m12" "yo1" "yo2"

但是mixedsort特别忽略了字符串的大小写,所以对 SortC 做类似的功能是行不通的。

我有几个要以这种方式排序的向量,它们包含示例中未包含的字符,因此找到一种通用的方法会很棒。

想法?也许我缺少一些明显的东西。谢谢。

4

1 回答 1

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))
于 2013-09-02T11:54:38.280 回答