如何对R中元素包含字母和数字的字符向量进行排序?

Posted

技术标签:

【中文标题】如何对R中元素包含字母和数字的字符向量进行排序?【英文标题】:How to sort a character vector where elements contain letters and numbers in R? 【发布时间】:2013-07-06 01:36:03 【问题描述】:

我有一个字符数组

cf <- c("V440","V457","V116","V327","V446","V108",
         "V155","V217","V120","V51","V477")

我想按降序对它进行排序,这样我就会得到这样的输出:

V51
V108
V116
V120
V155
V217
V327
V440
V446
V457
V477

我试过这样sort.list()

cf[sort.list(cf)]

得到了这个答案:

[1] "V108" "V116" "V120" "V155" "V217" "V327" "V440" "V446" "V457" "V477" "V51" 

并且还尝试了order() 并得到了相同的结果。

谁能帮帮我

【问题讨论】:

【参考方案1】:

试试“gtools”包中的mixedsort

> # install.packages("gtools") ## Uncomment if not already installed
> library(gtools)
> mixedsort(cf)
 [1] "V51"  "V108" "V116" "V120" "V155" "V217" "V327" "V440" "V446" "V457" "V477"

如果您不想使用mixedsort(不知道为什么不这样做),并且如果您的向量具有非常一致的模式(例如字母后跟数字),您也可以尝试类似的方法。 (注意:相对未经测试。

newvec <- c("V440", "V457", "V116", "V327", "V446", "V108", "V155", 
            "V217", "V120", "V51", "V477", "B22", "A10", "Z01")

newvec[order(gsub("([A-Z]+)([0-9]+)", "\\1", newvec), 
             as.numeric(gsub("([A-Z]+)([0-9]+)", "\\2", newvec)))]
#  [1] "A10"  "B22"  "V51"  "V108" "V116" "V120" "V155" "V217" "V327" "V440"
# [11] "V446" "V457" "V477" "Z01" 

【讨论】:

【参考方案2】:

这里有很多正确答案,这是另一种方式,只是为了好玩。

cf[order(nchar(cf), cf)]
# [1] "V51"  "V108" "V116" "V120" "V155" "V217" "V327" "V440" "V446" "V457" "V477"

【讨论】:

嗯,这将 c("ahoy", "hello", "hi") 排序为 "hi", "ahoy" 和 "hello" 这与人类对自然的期望不同比较器【参考方案3】:

在一行代码中使用str_sortfunction(来自stringr packg)的另一种解决方案

# install.packages("stringr") ## Uncomment if not already installed
library(stringr)

str_sort(cf, numeric = TRUE)

[1] "V51"  "V108" "V116" "V120" "V155" "V217" "V327" "V440" "V446" "V457" "V477"

【讨论】:

【参考方案4】:

只需刮掉前面的“V”字符即可构建排序向量。无需额外的花哨工具。

vals <- as.numeric(gsub("V","", cf))
cf[order(vals)]

[1] "V51"  "V108" "V116" "V120" "V155" "V217" "V327" "V440" "V446"
[10] "V457" "V477"

【讨论】:

【参考方案5】:

R 正确地按字母顺序排列字符串,这就是你得到这个结果的原因。

除了@Ananda 非常好的答案,如果您想使用基数 R,您可以使用 strsplit 从每个字符串中删除“V”,然后使用 as.numeric 将字符串转换为整数:

vals <- as.numeric(sapply(cf, FUN=function(x)strsplit(x, "V")[[1]][2]))

现在您可以使用 vals 对字符串进行排序

cf[order(vals)]

【讨论】:

【参考方案6】:

这是使用namessort 的基本方法(Ananda 的方法非常巧妙):

cf <- c("V440","V457","V116","V327","V446","V108",
         "V155","V217","V120","V51","V477")

cf2 <- as.numeric(gsub("[^[:digit:]]", "", cf))
names(cf2) <- seq_along(cf2)
cf[as.numeric(names(sort(cf2)))]

## > cf[as.numeric(names(sort(cf2)))]
##  [1] "V51"  "V108" "V116" "V120" "V155" "V217" "V327"
##  [8] "V440" "V446" "V457" "V477"

【讨论】:

以上是关于如何对R中元素包含字母和数字的字符向量进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何按字典顺序对 ArrayList 进行排序?

在C ++中按非ASCII顺序的第一个字母对字符串向量进行排序

对包含对象的向量的元素进行排序

oracle 表中如何对按含有字母和数字的编号来进行排序

如何对R中的列表中的元素进行排序?

对包含语义版本的字符向量进行排序