Сортировать фрейм данных на основе другого отсортированного значения столбца в R - PullRequest
1 голос
/ 21 апреля 2020

У меня есть фрейм данных, который отсортирован по одному столбцу (цифра c столбец) для назначения ранга. если значение этого столбца равно нулю, то упорядочить фрейм данных на основе другого символьного столбца для тех строк, которые имеют ноль в качестве значения в столбце нумерации c.

Но чтобы присвоить ранг, я должен рассмотреть var2, то есть причина, по которой я сортировал на основе var2, если в var2 есть какие-либо идентичные значения для этих строк, я должен рассмотреть var3, чтобы присвоить ранг. см. строки данных 2 и 3, значения var2 идентичны, в этом случае я должен рассмотреть var3, чтобы присвоить ранг. В случае, если var2 равен нулю, я должен отсортировать столбец var1 (символьный столбец) в алфавитном порядке и присвоить ранг. если var2 - нет рейтинга. см. приведенный ниже фрейм данных.

Ниже фрейм данных отсортирован в порядке убывания столбца var2, но var2 содержит ноль также, если var2 равен нулю. Я должен отсортировать фрейм данных на основе var1 для строк. которые имеют ноль в var2. Мне нужна сортировка по var1 для тех строк, у которых var2 равна нулю, а за ним следует NA в алфавитном порядке по var1.

    example:
    #      var1    var2    var3    rank
    # 1     c      556      45       1
    # 2     a      345      35       3
    # 3     f      345      64       2
    # 4     b      134      87       4
    # 5     z       0       34       5
    # 6     d       0       32       6
    # 7     c       0       12       7
    # 8     a       0       23       8
    # 9     e      NA      
    # 10    b      NA       

below is my code 
df <- data.frame(var1=c("c","a","f","b","z","d", "c","a", "e", "b", "ad", "gf", "kg", "ts", "mp"), var2=c(134, NA,345, 200, 556,NA, 345, 200, 150, 0, 25,10,0,150,0), var3=c(65,'',45,34,68,'',73,12,35,23,34,56,56,78,123))

# To break the tie between var3 and var2 
orderdf <- df[order(df$var2, df$var1, decreasing = TRUE), ] 

#assigning rank 
rankdf <- orderdf %>% mutate(rank = ifelse(is.na(var2),'', seq(1:nrow(orderdf))))

ожидаемый результат - сортировка var1 по алфавиту, если значение var2 равно нулю (для тех строки со значением var2, равным нулю)

    expected output:
    #      var1    var2    var3    rank
    # 1     c      556      45       1
    # 2     a      345      35       3
    # 3     f      345      64       2
    # 4     b      134      87       4
    # 5     a       0       34       5
    # 6     c       0       32       6
    # 7     d       0       12       7
    # 8     z       0       23       8
    # 9     b      NA      
    # 10    e      NA       

Ответы [ 4 ]

1 голос
/ 21 апреля 2020

С dplyr вы можете использовать

df %>% 
  arrange(desc(var2), var1)

, а затем создать столбец rank


РЕДАКТИРОВАТЬ

Следующий код немного громоздким, но он выполняет свою работу. В основном он упорядочивает строки, в которых var2 равен или отличается от нуля отдельно, затем объединяет два упорядоченных кадра данных вместе и, наконец, создает столбец rank.

Данные

df <- data.frame(
  var1 = c("c","a","f","b","z","d", "c","a", "e", "z", "ad", "gf", "kg", "ts", "mp"), 
  var2 = c(134, NA,345, 200, 556,NA, 345, 200, 150, 0, 25,10,0,150,0), 
  var3 = as.numeric(c(65,'',45,34,68,'',73,12,35,23,34,56,56,78,123))
)
df
#    var1 var2 var3
# 1     c  134   65
# 2     a   NA   NA
# 3     f  345   45
# 4     b  200   34
# 5     z  556   68
# 6     d   NA   NA
# 7     c  345   73
# 8     a  200   12
# 9     e  150   35
# 10    z    0   23
# 11   ad   25   34
# 12   gf   10   56
# 13   kg    0   56
# 14   ts  150   78
# 15   mp    0  123

Код

df %>% 
# work on rows with var2 different from 0 or NA
  filter(var2 != 0) %>% 
  arrange(desc(var2), desc(var3)) %>% 
# merge with rows with var2 equal to 0 or NA
  bind_rows(df %>% filter(var2 == 0 | is.na(var2)) %>% arrange(var1)) %>% 
  arrange(desc(var2)) %>% 
# create the rank column only for the rows with var2 different from NA
  mutate(
    rank = seq_len(nrow(df)),
    rank = ifelse(is.na(var2), NA, rank)
    )

Выход

#    var1 var2 var3 rank
# 1     z  556   68    1
# 2     c  345   73    2
# 3     f  345   45    3
# 4     b  200   34    4
# 5     a  200   12    5
# 6    ts  150   78    6
# 7     e  150   35    7
# 8     c  134   65    8
# 9    ad   25   34    9
# 10   gf   10   56   10
# 11   kg    0   56   11
# 12   mp    0  123   12
# 13    z    0   23   13
# 14    a   NA   NA   NA
# 15    d   NA   NA   NA
0 голосов
/ 21 апреля 2020

Использование data.table

library(data.table)
setDT(df)[order(-var2, var1)][, rank := seq_len(.N)][]

данных

df <- structure(list(var1 = structure(c(3L, 1L, 6L, 2L, 7L, 4L, 3L, 
1L, 5L, 2L), .Label = c("a", "b", "c", "d", "e", "f", "z"), class = "factor"), 
var2 = c(1456L, 456L, 345L, 134L, 0L, 0L, 0L, 0L, NA, NA)), 
class = "data.frame", row.names = c(NA, -10L))
0 голосов
/ 21 апреля 2020

Используя только базовую функцию R order(), сортируйте сначала в порядке убывания var2, затем в порядке возрастания var1, чтобы отсортировать данные, передав последующий целочисленный вектор в квадратные скобки

df[order(-df$var2, df$var1), ]

Добавление столбца рейтинга тоже тогда просто

df[order(-df$var2, df$var1), "rank"] <- 1:length(df$var1)
0 голосов
/ 21 апреля 2020

Вы можете сделать это в базе R, используя order:

cols <- c('var1', 'var2')
remaining_cols <- setdiff(names(df), cols)
df1 <- df[cols]
cbind(transform(df1[with(df1, order(-var2, var1)), ], 
                rank = seq_len(nrow(df1))), df[remaining_cols])


#   var1 var2 rank var3
#1     c  556    1   45
#2     a  345    2   35
#3     f  345    3   64
#4     b  134    4   87
#8     a    0    5   34
#7     c    0    6   32
#6     d    0    7   12
#5     z    0    8   23
#10    b   NA    9   10
#9     e   NA   10   11

data

df <- structure(list(var1 = structure(c(3L, 1L, 6L, 2L, 7L, 4L, 3L, 
1L, 5L, 2L), .Label = c("a", "b", "c", "d", "e", "f", "z"), class = "factor"), 
var2 = c(556L, 345L, 345L, 134L, 0L, 0L, 0L, 0L, NA, NA), 
var3 = c(45L, 35L, 64L, 87L, 34L, 32L, 12L, 23L, 10L, 11L
)), class = "data.frame", row.names = c(NA, -10L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...