【问题标题】:Order a "mixed" vector (numbers with letters)订购“混合”向量(带字母的数字)
【发布时间】:2013-12-22 04:36:16
【问题描述】:

如何订购像

这样的向量
c("7","10a","10b","10c","8","9","11c","11b","11a","12") -> alph

alph
[1] "7","8","9","10a","10b","10c","11a","11b","11c","12"

并使用它对data.frame进行排序,例如

V1 <- c("A","A","B","B","C","C","D","D","E","E")
V2 <- 2:1 
V3 <- alph
df <- data.frame(V1,V2,V3)

并对行进行排序以获得(顺序V2,然后是V3)

 V1 V2  V3
C  1   9
A  1 10a
B  1 10c
D  1 11b
E  1  12
A  2   7
C  2   8
B  2 10b
E  2 11a
D  2 11c

【问题讨论】:

  • 不要使用data.frame(cbind(...)),直接使用data.frame(...)即可。通过调用cbind,您可以创建一个包含V1V2V3字符矩阵,这可能不是您想要的。

标签: r sorting


【解决方案1】:
> library(gtools)
> mixedsort(alph)

[1] "7"   "8"   "9"   "10a" "10b" "10c" "11a" "11b" "11c" "12" 

要对 data.frame 进行排序,请改用 mixedorder

> mydf <- data.frame(alph, USArrests[seq_along(alph),])
> mydf[mixedorder(mydf$alph),]

            alph Murder Assault UrbanPop Rape
Alabama        7   13.2     236       58 21.2
California     8    9.0     276       91 40.6
Colorado       9    7.9     204       78 38.7
Alaska       10a   10.0     263       48 44.5
Arizona      10b    8.1     294       80 31.0
Arkansas     10c    8.8     190       50 19.5
Florida      11a   15.4     335       80 31.9
Delaware     11b    5.9     238       72 15.8
Connecticut  11c    3.3     110       77 11.1
Georgia       12   17.4     211       60 25.8

mixedorder 在多个向量(列)上

显然mixedorder 无法处理多个向量。我创建了一个函数,通过将所有字符向量转换为具有混合排序级别的因子,并将所有向量传递给标准order 函数来规避这一点。

multi.mixedorder <- function(..., na.last = TRUE, decreasing = FALSE){
    do.call(order, c(
        lapply(list(...), function(l){
            if(is.character(l)){
                factor(l, levels=mixedsort(unique(l)))
            } else {
                l
            }
        }),
        list(na.last = na.last, decreasing = decreasing)
    ))
}

但是,在您的特定情况下,multi.mixedorder 会得到与标准 order 相同的结果,因为 V2 是数字。

df <- data.frame(
    V1 = c("A","A","B","B","C","C","D","D","E","E"),
    V2 = 19:10,
    V3 = alph,
    stringsAsFactors = FALSE)

df[multi.mixedorder(df$V2, df$V3),]

   V1 V2  V3
10  E 10  12
9   E 11 11a
8   D 12 11b
7   D 13 11c
6   C 14   9
5   C 15   8
4   B 16 10c
3   B 17 10b
2   A 18 10a
1   A 19   7

请注意

  • 19:10 等价于 c(19:10)c 表示 concat,即从许多短向量中生成一个长向量,但在您的情况下,您只有一个向量 (19:10),因此无需连接任何内容。但是,在 V1 的情况下,您有 10 个长度为 1 的向量,因此您需要像之前那样进行连接。
  • 您需要stringsAsFactors=FALSE 才能不将V1V3 转换为(排序错误的)因子(这是默认值)。

【讨论】:

  • 我尝试了这个解决方案,但我不知道如何使用它对两列进行排序(我编辑了一个示例)。
  • 看来mixedorder 不支持多列(多么奇怪!),但我可以破解你一个迂回的解决方案。以前一直想做这种性质的事情。
  • 你说得对,我的例子真的很糟糕,对不起。但是尝试使用 V2 = 2:1 的解决方案,它不再起作用了……不是吗?
  • 别担心,R 中的很多东西一开始并不明显 :) 你是对的,如果V2 中有联系,它就不起作用。今天晚些时候我会看看它。
  • @TiagoBruno 确保您使用的是最近发布的最新版本的 ggplot2。在旧版本中,事情的顺序一直很痛苦,虽然我没有在新版本中尝试过,但我知道它已经被大量重写和改进,所以我希望他们已经解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多