【问题标题】:R: mixedsort on multiple vectors (columns)R:对多个向量(列)进行混合排序
【发布时间】:2019-01-08 10:09:00
【问题描述】:

这是this question 的后续,被标记为a duplicate to this,但建议的解决方案不起作用。

我有以下data.frame

set.seed(1)
mydf <- data.frame(A=paste(sample(LETTERS, 4), sample(1:20, 20), sep=""),
        B=paste(sample(1:20, 20), sample(LETTERS, 4), sep=""),
        C=sample(LETTERS, 20), D=sample(1:100, 20), value=rnorm(20))

> mydf
     A   B C  D       value
1   G5  6N T  9 -0.68875569
2  J18  8T R 87 -0.70749516
3  N19  1A L 34  0.36458196
4  U12  7K Z 82  0.76853292
5  G11 14N J 98 -0.11234621
6   J1 20T F 32  0.88110773
7   N3 17A B 45  0.39810588
8  U14 19K W 83 -0.61202639
9   G9 15N U 80  0.34111969
10 J20  3T I 36 -1.12936310
11  N8  9A K 70  1.43302370
12 U16 16K G 86  1.98039990
13  G6 10N M 39 -0.36722148
14  J7 18T D 62 -1.04413463
15 N13  5A Y 35  0.56971963
16  U4 11K N 28 -0.13505460
17 G17  4N O 64  2.40161776
18 J15  2T C 17 -0.03924000
19  N2 12A P 59  0.68973936
20 U10 13K X 10  0.02800216

我想按照AD的列排序,但是AD是混用的,所以需要自然排序。

我知道我可以应用常规排序,例如:

mydf2 <- mydf[do.call(order, c(mydf[1:4], list(decreasing = FALSE))),]

> mydf2
     A   B C  D       value
5  G11 14N J 98 -0.11234621
17 G17  4N O 64  2.40161776
1   G5  6N T  9 -0.68875569
13  G6 10N M 39 -0.36722148
9   G9 15N U 80  0.34111969
6   J1 20T F 32  0.88110773
18 J15  2T C 17 -0.03924000
2  J18  8T R 87 -0.70749516
10 J20  3T I 36 -1.12936310
14  J7 18T D 62 -1.04413463
15 N13  5A Y 35  0.56971963
3  N19  1A L 34  0.36458196
19  N2 12A P 59  0.68973936
7   N3 17A B 45  0.39810588
11  N8  9A K 70  1.43302370
20 U10 13K X 10  0.02800216
4  U12  7K Z 82  0.76853292
8  U14 19K W 83 -0.61202639
12 U16 16K G 86  1.98039990
16  U4 11K N 28 -0.13505460

但这不是我需要的结果。我需要109 之后,而不是在1 之后(您可以查看A 列以查看它不是我需要的顺序。)

在我原来的问题的cmets中,建议使用multi.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)
    ))
}

mydf3 <- mydf[do.call(multi.mixedorder, c(mydf[1:4], list(decreasing = FALSE))),]

> mydf3
    A   B C  D       value
5  G11 14N J 98 -0.11234621
17 G17  4N O 64  2.40161776
1   G5  6N T  9 -0.68875569
13  G6 10N M 39 -0.36722148
9   G9 15N U 80  0.34111969
6   J1 20T F 32  0.88110773
18 J15  2T C 17 -0.03924000
2  J18  8T R 87 -0.70749516
10 J20  3T I 36 -1.12936310
14  J7 18T D 62 -1.04413463
15 N13  5A Y 35  0.56971963
3  N19  1A L 34  0.36458196
19  N2 12A P 59  0.68973936
7   N3 17A B 45  0.39810588
11  N8  9A K 70  1.43302370
20 U10 13K X 10  0.02800216
4  U12  7K Z 82  0.76853292
8  U14 19K W 83 -0.61202639
12 U16 16K G 86  1.98039990
16  U4 11K N 28 -0.13505460

【问题讨论】:

    标签: r sorting dataframe natural-sort


    【解决方案1】:

    OK 解决了,multi.mixedsort 函数需要修复才能处理因素:

    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 {
                    factor(as.character(l), levels=mixedsort(levels(l)))
                }
            }),
            list(na.last = na.last, decreasing = decreasing)
        ))
    }
    

    否则将mydf中的所有因子列转换为字符,用:

    mydf[] <- lapply(mydf, as.character)
    

    但是有了修复,这应该是不需要的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 2012-11-07
      • 1970-01-01
      • 2011-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多