Как изменить порядок фреймов данных в шаблоне в R

#r #dataframe #dplyr #data.table

#r #фрейм данных #dplyr #данные.таблица

Вопрос:

Я хочу изменить следующий фрейм данных в определенной последовательности.

 Stage       Score 
W-3         25
W-3         2 Min 10 Sec
W-2         45
W-2         1 Min 34 Sec
W-1         75
W-1         1 Min 04 Sec
 

Я хочу изменить его в следующем порядке.

 Stage       Score
W-1         75
W-1         1 Min 04 Sec
W-2         45
W-2         1 Min 34 Sec
W-3         25
W-3         2 Min 10 Sec
 

Я использую df<- df[seq(dim(df)[1],1),] , но это не сработало.

Ответ №1:

Другой базовый вариант R, использующий order ave

 df[with(df, order(Stage, ave(1:nrow(df), Stage, FUN = seq_along))), ]
 

что дает

   Stage        Score
5   W-1           75
6   W-1 1 Min 04 Sec
3   W-2           45
4   W-2 1 Min 34 Sec
1   W-3           25
2   W-3 2 Min 10 Sec
 

Данные

 > dput(df)
structure(list(Stage = c("W-3", "W-3", "W-2", "W-2", "W-1", "W-1"
), Score = c("25", "2 Min 10 Sec", "45", "1 Min 34 Sec", "75",
"1 Min 04 Sec")), row.names = c(NA, -6L), class = "data.frame")
 

Ответ №2:

Мы можем использовать factor с levels указанным в rev предыдущем порядке unique элементов ‘Stage’

 library(dplyr)
df2 <- df1 %>%
    arrange(factor(as.character(Stage), 
             levels = rev(unique(as.character(Stage)))))
 

И то же самое со столбцом «Дата»

 df1 %>%
    arrange(factor(as.character(Date), 
             levels = rev(unique(as.character(Date)))))
 

-вывод

 # Stage        Score       Date
#1   W-1 1 Min 04 Sec 2020-12-15
#2   W-1           75 2020-12-14
#3   W-2 1 Min 34 Sec 2020-12-13
#4   W-2           45 2020-12-12
#5   W-3 2 Min 10 Sec 2020-12-11
#6   W-3           25 2020-12-10
 

Или с помощью base R

 df2 <- df1[order(factor(df1$Stage, levels = rev(unique(df1$Stage)))),]
 

данные

 df1 <- structure(list(Stage = c("W-3", "W-3", "W-2", "W-2", "W-1", "W-1"
), Score = c("25", "2 Min 10 Sec", "45", "1 Min 34 Sec", "75", 
"1 Min 04 Sec"), Date = structure(18606:18611, class = "Date")),
row.names = c(NA, 
-6L), class = "data.frame")
 

Комментарии:

1. то же самое не работает с форматом даты (гггг-мм-дд).

2. @SophiaWilson можете ли вы обернуть его as.character . в качестве обновленного сообщения

3. Не повезло с датой.

4. @SophiaWilson я обновил сообщение. Теперь он работает как с датой, так и с буквенно-цифровым

Ответ №3:

Мы также можем использовать mixedorder from gtools .

 df <- data.frame("Stage" = c('W-3', 'W-3', 'W-2',
                             'W-2', 'W-1', 'W-1'),
                 "Score" = c(25, '2 Min 10 Sec', 45,
                             '1 Min 34 Sec', 75, '1 Min 04 Sec' ))

library(gtools)
df[mixedorder(df$Stage, decreasing = T), ]
 

   Stage        Score
5   W-1           75
6   W-1 1 Min 04 Sec
3   W-2           45
4   W-2 1 Min 34 Sec
1   W-3           25
2   W-3 2 Min 10 Sec