R: mixedsort по нескольким векторам (столбцы) - PullRequest
0 голосов
/ 08 января 2019

Это продолжение этого вопроса , который был помечен как дубликат этого , но предлагаемое решение не работает.

У меня есть следующее 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

Я хочу заказать его по столбцам A - D, но A и D смешаны, поэтому натуральный порядок обязателен.

Я знаю, что могу применять регулярные заказы, например:

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

Но это не тот результат, который мне нужен. Мне нужно 10 после 9, а не после 1 (вы можете проверить столбец A, чтобы увидеть, что он находится не в том порядке, в котором я нуждаюсь).

В комментариях к моему первоначальному вопросу было предложено использовать функцию 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

1 Ответ

0 голосов
/ 08 января 2019

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)

но с исправлением это не нужно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...